关于如何理解nil

来源:1-1 Google资深工程师深度讲解go语言

慕村0176662

2022-04-09

func main() {

//通过打印发现s 是有结构的 [] len=0,cap=0
//但是nil在objectc语言中也有定义是一个宏,值是0,
//但是s是一个结构或者类型,按照c++的理解,只要一声明就会开辟内存
//或者说只有指针类型才会初始值为nil,但是go都是值类型
var s []int

fmt.Println(s == nil)
printArrary(s)

}

写回答

2回答

ccmouse

2022-05-09

这个问题很好。答案是:nil是一个值。对于不同的类型,它实际上会分配不一样的数据结构。这个问题和另一个问题结合起来看。

我这里通过unsafe.SizeOf来查看nil的分配情况。https://go.dev/play/p/FBbFP1HKuZa 

对于[]int,它的结构是:指向底层数组的指针,len,cap。指针和len, cap两个int各占8字节,所以总共分配了24字节。不管是nil还是通过make生成的切片。https://blog.csdn.net/Peerless__/article/details/121304665 

对于interface,它的结构是一个指向类型信息的指针,一个指向数据的指针。我们在结构体的值类型中也查看过这两个信息。所以即使是nil,它一样会分配内存,两个指针,所以16字节。https://blog.csdn.net/dongqiang51/article/details/122691441 

那么一般的指针类型比如*int,定义一个指针类型的变量,就会分配8个字节,其值为0。


1
2
慕村0176662
判断等不等于nil,不同的类型所做的处理不一样,虽然在语法上我们只写了==
2022-05-10
共2条回复

慕村0176662

提问者

2022-05-09

明白了,var s [] int 定义的是一个切片,那么默认肯定是nil ,类似于其他语言的对象类型,如果在函数内定义数组那么变量肯定放的是数据了,和其他语言一样无非看变量里放的是啥,传的啥就是啥,java对象都是在堆内分配的,所以基础类型是值传递,对象是引用传递,统一点就是变量放啥传啥,go语言也是这样吧,没有必要非说是值传递吧,

还有只所以能对等于nil的切片打印结构,不是说变量有结构,这个变量所占的内存要大于一个指针的大小,而是打印的这段代码在编译的时候进行了处理,是这样么?

0
0

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程