nil是Golang中使用频率较高的标识符,有很多初学者会将Golang中的nil看作其它语言中的null,这在部分是正确的。我们先看下nil在 buildin/buildin.go 中的定义:
1
2
3
// 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
通过上面的注释可以看出Golang中的nil可以用作pointer、map、slice、func、channel、interface类型的零值。nil并不是一个关键字(其它语言中null同样不是关键字),它只是一个变量名,如果我们自己声明一个nil变量,那么它就会被同名变量遮挡:
1
2
3
4
5
6
7
8
package main
import "fmt"
func main(){
nil := 123
fmt.Println(nil) // 123
}
interface
当interface与一个值做比较的时候,会同时比较type和value,只有在type和value都相等的时候,才会认为相等。所以 (*int)(nil)和(interface{})(nil) 是不相等的,因为它们的type不同。
当一个interface的type和value都为空的时候才等于nil。如下面例子中变量a虽然打印出了nil,但是它的类型却是*B:
1
2
3
4
5
6
type A interface{}
type B struct{}
var a A = (*B)(nil)
println(a) // <nil>
println(a == nil) //false
可见Golang中的nil和其它语言中的null还是有很大区别的,它并不完全等同于其它语言中的null,这对于Golang初学者来说算作一个”坑”了。