golang 接口值: 一个包含 nil 指针的接口不是 nil 接口.
一个不包含任何值的 nil 接口值和一个刚好包含 nil 指针的接口值是不同的.
接口值由两个部分组成:
- 一个具体的类型
- 那个类型的值
它们被称为接口的动态类型和动态值.
type | value |
---|---|
x | x |
接口的零值是指动态类型为nil, 动态值也为nil.
type | value |
---|---|
nil | nil |
这样的接口才能满足 接口值 == nil.
var a interface{}
fmt.Println(a == nil) // true
一个不包含任何值的 nil 接口值:
interface 类型变量的动态类型和动态值都为 nil. 比如 nil, 或者:
var a interface{}
fmt.Println(a) // a为nil
一个刚好包含 nil 指针的接口值:
赋值给后,interface 类型变量的动态类型不为 nil,动态值为 nil.
var a interface{}
var b *string
a = b
fmt.Println(a) // 此时a的动态类型为*string,动态值为nil
这两种对象比较:
func main(){
var a interface{} // nil
var b *string // nil
a = b
fmt.Println(a == nil) // false
fmt.Println(b == nil) // true
fmt.Println(b == a) // true
}
-
a
= nil 为 false: b 赋值给 a, a 的动态类型为 *string, 动态值为 nil, 所以 a =
nil 为 false.// 空接口 type eface struct { _type *_type // 类型信息 data unsafe.Pointer // 指向数据的指针 } // 带有方法的接口 type iface struct { tab *itab // 存储type信息还有结构实现方法的集合 data unsafe.Pointer // 指向数据的指针 }
根据 interface 的底层实现, a = b 实则是 a.data = unsafe.Pointer(&b). a = nil 才是 a.data = nil.
-
b == nil 为 true: b 是一个空的指针(非接口)类型.
-
b == a 为 true: 值都为 nil, b 是一个空的指针(非接口)类型.