go 的反射

2022-11-12  本文已影响0人  wayyyy

go 中的 interface{} 有两个用途:
1、是接口定义约束
2、万能类型

interface 定义是这样的:

type iface struct {
    tab *itab
    data unsafe.Pointer
}

type eface struct {
    _type *_type
    data unsafe.Pointer
}

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

interface 和 nil 的比较踩坑
type Worker interface {
    Work() error
}

type Qstruct struct{}

func (q *Qstruct) Work() error {
    return nil
}

// 返回一个 nil 
func findSomething() *Qstruct {
    return nil
}

func main() {
    var v Worker

    v = findSomething()
    if v != nil {
        // 走的是这个分支
        fmt.Printf("v(%v) != nil\n", v)
    } else {
        fmt.Printf("v(%v) == nil\n", v)
    }
}

前置知识:

  1. interface 变量新创建的时候是 nil ,则这 16 个字节是全 0 值;
  2. interface 变量的 nil 判断,逻辑是判断首 8 字节是否是 0 值;

关键就是 v = findSomething() 这行代码。这个是一个赋值操作,左边是一个接口变量,函数 findSomething 返回的是一个具体类型指针。所以,它一定会把接口变量 iface 前 8 字节设置非零字段的,因为有具体类型(无论具体类型是否是 nil 指针)。

上一篇下一篇

猜你喜欢

热点阅读