golang中的<code>nil</code>,很多人都误以为与Java、PHP等编程语言中的null一样。但是实际上Golang的niu复杂得多了,如果不信,那我们继续往下阅读。
<code>nil</code> 为预声明的标示符,定义在<code>builtin/builtin.go</code>,
按照Go语言规范,任何类型在未初始化时都对应一个零值:布尔类型是false,整型是0,字符串是"",而指针、函数、interface、slice、channel和map的零值都是nil。
PS:这里没有说结构体struct的零值为nil,因为struct的零值与其属性有关
<code>nil</code>没有默认的类型,尽管它是多个类型的零值,必须显式或隐式指定每个nil用法的明确类型。
如果关注过golang关键字的同学就会发现,里面并没有<code>nil</code>,也就是说<code>nil</code>并不是关键字,那么就可以在代码中定义<code>nil</code>,那么<code>nil</code>就会被隐藏。
<code>nil</code>类型的所有值的内存布局始终相同,换一句话说就是:不同类型<code>nil</code>的内存地址是一样的。
业务中一般将<code>nil</code>值表示为异常。nil值的大小始终与其类型与<code>nil</code>值相同的<code>non-nil</code>值大小相同。因此, 表示不同零值的nil标识符可能具有不同的大小。
大小是编译器和体系结构所依赖的。以上打印结果为64位体系结构和正式 Go 编译器。对于32位体系结构, 打印的大小将是一半。
对于正式 Go 编译器, 同一种类的不同类型的两个nil值的大小始终相同。例如, 两个不同的切片类型 ( []int和[]string) 的两个nil值始终相同。
1.不同类型的<code>nil</code>是不能比较的。
在 Go 中, 两个不同可比较类型的两个值只能在一个值可以隐式转换为另一种类型的情况下进行比较。具体来说, 有两个案例两个不同的值可以比较:
两个值之一的类型是另一个的基础类型。
两个值之一的类型实现了另一个值的类型 (必须是接口类型)。
<code>nil</code>值比较并没有脱离上述规则。
2.同一类型的两个<code>nil</code>值可能无法比较 因为golang中存在map、slice和函数类型是不可比较类型,它们有一个别称为<code>不可比拟的类型</code>,所以比较它们的<code>nil</code>亦是非法的。
<code>不可比拟的类型</code>的值缺是可以与“纯nil”进行比较。
3.两<code>nil</code>值可能不相等
如果两个比较的nil值之一是一个接口值, 而另一个不是, 假设它们是可比较的, 则比较结果总是 false。原因是在进行比较之前, 接口值将转换为接口值的类型。转换后的接口值具有具体的动态类型, 但其他接口值没有。这就是为什么比较结果总是错误的。
1.函数返回
因为<code>error</code>是接口类型所以<code>error</code>类型没有报错。
2.map的nil key map的key为指针、函数、interface、slice、channel和map,则key可以为nil。
nil之所以比较难以理解因为我们经常混淆了nil值和nil类型,希望各位同学细细品味其中区别。
本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/1980197