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)
}
}
前置知识:
- interface 变量新创建的时候是 nil ,则这 16 个字节是全 0 值;
- interface 变量的 nil 判断,逻辑是判断首 8 字节是否是 0 值;
关键就是 v = findSomething()
这行代码。这个是一个赋值操作,左边是一个接口变量,函数 findSomething 返回的是一个具体类型指针。所以,它一定会把接口变量 iface
前 8 字节设置非零字段的,因为有具体类型(无论具体类型是否是 nil 指针)。
网友评论