请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于如何理解nil

func main() {

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

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

}

正在回答 回答被采纳积分+3

2回答

ccmouse 2022-05-09 22:52:48

这个问题很好。答案是: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 回复 有任何疑惑可以回复我~
  • 提问者 慕村0176662 #1
    好的,谢谢
    回复 有任何疑惑可以回复我~ 2022-05-09 23:53:17
  • 提问者 慕村0176662 #2
    判断等不等于nil,不同的类型所做的处理不一样,虽然在语法上我们只写了==
    回复 有任何疑惑可以回复我~ 2022-05-10 00:01:16
提问者 慕村0176662 2022-05-09 23:30:39
明白了,var s [] int 定义的是一个切片,那么默认肯定是nil ,类似于其他语言的对象类型,如果在函数内定义数组那么变量肯定放的是数据了,和其他语言一样无非看变量里放的是啥,传的啥就是啥,java对象都是在堆内分配的,所以基础类型是值传递,对象是引用传递,统一点就是变量放啥传啥,go语言也是这样吧,没有必要非说是值传递吧,

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

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信