理解Golang中的nil
作者:互联网
参考:
常用的nil
在写程序的时候经常会遇到nil
这个词,比如说错误判断:
f, err := os.Open(filePath)
if err != nil {
panic(err)
}
这很容易理解,但是有如果对nil
与nil
进行比较,如下:
fmt.Println(nil== nil)
我第一反应是true,但是能作为面试题,肯定不会那么简单。显然是我太菜了,那么今天就来扒一扒nil
nil
的官方定义
查看Golang的官方定义builtin - The Go Programming Language (golang.org):
nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
翻译之后,总结起来,nil是:
- 一个标识符(并不是关键字)
- 预先定义的零值
- 针对
- pointer
- channel
- func
- interface
- map
- slice
nil
是一个标识符
nil
不是一个关键字,只是一个标识符。这就说明你可以自己定义一个变量去覆盖它。
这是可以编译通过的,但是不建议那么做。
nil
有类型吗
从定义可知,nil
是多个类型的零值,这些类型之间的差别很大,那么nil
怎么能表示这些零值,而且nil有类型吗?
我尝试将nil赋值给变量a并打印出来,会显示use of untyped nil
;
也就是说,nil是没有默认类型的,使用nil的时候必需提供充足的上下文信息来让编译器推断其类型。
使用nil
比较
nil与nil进行比较
回归上面的面试题,对nil和nil进行比较,结果如下:
编译没有通过,显示的错误为操作==在nil中没有定义。==
符号对于nil
来说是一种未定义的操作,所以不可以来比较两个nil
。
不同类型的nil比较
不同类型之间的nil进行比较,结果如何呢?
可以看到,不同类型之间的nil是无法进行比较的,显示为mismatched types
各种类型的零值与地址
那么,不同类型的零值实际上是什么?我们尝试来打印各种类型nil的实际GO语法表示与地址
总结起来如下:
类型 | 值的Go语法表示 | address |
---|---|---|
map | map[int]string(nil) | 0x0 |
pointer (*int) | (*int)(nil) | 0x0 |
channel | (chan int)(nil) | 0x0 |
slice | []int(nil) | 0x0 |
func | (func())nil | 0x0 |
interface | <nil> | %!p(<nil>) |
可以看到大部分地址都是相同的,每种类型nil的实际表示并不是一致的,所以不同类型nil不能进行比较。
总结
总的来说,nil值一个针对map等类型预先定义的零值的标识符。由于不是关键字,所以写代码中要注意不要使用nil作为变量名。nil的类型是不定的,会根据具体的定义环境而发生改变,这就要求我们在对nil进行比较时要特别注意。
标签:定义,nil,int,Golang,理解,类型,零值,比较 来源: https://blog.csdn.net/weixin_38371073/article/details/116262913