GO结构体的空指针和interface{}类型的区别


写在前面

直接上代码

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{}类型,还没初始化
  • 第三行:*Personinterface{}是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>

第五行比较难懂,希望讲清楚了。


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录