本文是Francesc Campoy在GoConf
上做的Understanding Nil演讲的笔记。
(1)nil
没有type
。
(2)在Go
语言中,未显示初始化的变量拥有其类型的zero value
。共有6
种类型变量的zero value
是nil
:pointer
,slice
,map
,channel
,function
和interface
。具体含义如下:
类型 | nil值含义 |
---|---|
pointer | 指向nothing |
slice | slice变量中的3个成员值:buf为nil(没有backing array),len和cap都是0 |
map,channel,function | 一个nil pointer,指向nothing |
interface | interface包含”type, value”,一个nil interface必须二者都为nil:”nil, nil” |
对于interface
来说,正因为需要<type, value>
这个元组中两个值都为nil
,interface
值才是nil
。所以需要注意下面两点:
a)Do not declare concrete error vars:
func do() error {
var err *doError // nil of type *doError
return err // error (*doError, nil)
}
func main() {
err := do() // error (*doError, nil)
fmt.Println(err == nil) // false
}
b)Do not return concrete error types:
func do() *doError {
return nil // nil of type *doError
}
func main() {
err := do() // nil of type *doError
fmt.Println(err == nil) // true
}
func do() *doError {
return nil // nil of type *doError
}
func wrapDo() error { // error (*doError, nil)
return do() // nil of type *doError
}
func main() {
err := wrapDo() // error (*doError, nil)
fmt.Println(err == nil) // false
}
(3)nil
一些有用的使用场景:
类型 | nil值使用场景 |
---|---|
pointer | methods can be called on nil receivers |
slice | perfectly valid zero values |
map | perfect as read-only values(往nil map添加成员会导致panic) |
channel | essential for some concurrency patterns |
function | needed for completeness |
interface | the most used signal in Go (err != nil) |