写在前面
直接上代码
type People struct {
Gender bool
Name string
}
func main() {
var data *People
var in interface{}
fmt.Println(data, data == nil)
fmt.Println(in, in == nil)
fmt.Println(data == in)
fmt.Printf("%v,%p,%v,%p\n", data, &data, in, &in)
in = data
fmt.Println(in, in == nil)
fmt.Printf("%v,%p,%v,%p\n", data, &data, in, &in)
}
结果
<nil> true
<nil> true
false
<nil>,0xc000012028,<nil>,0xc000014250
<nil> false
<nil>,0xc000012028,<nil>,0xc000014250
分析
你能解释第四行为什么是false吗?
- 第一行:
<nil> true
很容易理解,因为data是指向Person结构冲突的空指针 - 第二行:
<nil> true
也可以理解,因为in是interafce{}
类型,还没初始化 - 第三行:
*Person
和interface{}
是2个不同的类型,所以虽然data和in的值都是nil,但是他们的类型不一样,所以是false - 第四行:可以看到data的内存地址
0xc000012028
存的是<nil>
,而p的内存地址0xc000014250
存的也是<nil>
- 第五行:这个时候in的值不是nil了,而是data的值。虽然data的值是nil,但是这里比较的是
in==nil
,而不是比较data==nil
,所以用in直接跟nil比较他们就不相等了。 - 第六行:打印出来的in的值是
nil
,这个nil
是data的值,如果这个时候打印in的类型,fmt.Println(reflect.TypeOf(in))
结果是*main.People
,而在in=data
赋值之前答应in的类型,结果是<nil>
第五行比较难懂,希望讲清楚了。