Go语言中的nil

Golang nil

Posted by alovn on July 21, 2021

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初学者来说算作一个”坑”了。