欢迎光临散文网 会员登陆 & 注册

Go什么情况nil != nil

2023-05-13 15:19 作者:误入歧途的先森  | 我要投稿



上述代码执行结果竟然是:

interface 变量定义是一个 16 个字节的结构体,首 8 字节是类型字段,后 8 字节是数据指针。普通的 interface 是 iface 结构,interface{} 对应的是 eface 结构;

interface 变量新创建的时候是 nil ,则这 16 个字节是全 0 值;

interface 变量的 nil 判断,汇编逻辑是判断首 8 字节是否是 0 值;

非空接口interface具体类型:

type iface struct {

    tab *itab // 接口本身信息接口方法,并且存储具体类型所实现的信息

    data unsafe.Pointer // 内存地址

}

空接口具体类型:

type eface struct {

    _type *_type // 具体类型信息

    data unsafe.Pointer // 内存地址

}

type itab struct {

     inter *interfacetype // 包含接口类型typ,包名,方法切面的结构体指针

     _type *_type // 下面说

    // 当前类型的哈希值,runtime基于这个值构建类型映射表,加速类型比较和查找

     hash  uint32 // copy of _type.hash. Used for type switches.

     _     [4]byte // 4字节用于内存对齐

     fun   [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.  // 接口方法中的一个存储在这里,如果fun[0]是0的话默认不是某个结构体的接口

}

type _type struct {

     size       uintptr // 表示此类型的数据需要占用多少字节的存储空间

     ptrdata    uintptr // size of memory prefix holding all pointers ptrdata 表示数据的前多少字节包含指针,用来在应用写屏障时优化范围大小

     hash       uint32 // 当前类型的哈希值,runtime基于这个值构建类型映射表,加速类型比较和查找

     tflag      tflag // 额外的类型标识,目前由4个独立的二进制位组合而成。

     align      uint8 // 表示当前类型变量的对齐边界

     fieldAlign uint8 // 表示当前类型的 struct 字段的对齐边界

     kind       uint8 // 表示当前类型所属的分类,目前 Go语言的 reflect 包中定义了 40 种有效分类

     equal func(unsafe.Pointer, unsafe.Pointer) bool // 用来比较两个当前类型的变量是否相等

     gcdata    *byte // 和垃圾回收相关,GC 扫描和写屏障用来追踪指针

     str       nameOff // 偏移,通过 str 可以找到当前类型的名称等文本信息

     ptrToThis typeOff // 偏移,假设当前类型为 T,通过它可以找到类型 * T的类型元数据

}

type interfacetype struct {

     typ     _type // 接口类型typ

     pkgpath name // 包路径名pkgpath

     mhdr    []imethod // 存储接口方法集的切片mhdr

}

我们进行空接口和非空接口类型变量赋值的时候,返回如果是nil的接口体指针,就会导致,*itab 或者 *_type不是nil,是有类型指针的,这块大家需要注意!

Go什么情况nil != nil的评论 (共 条)

分享到微博请遵守国家法律