深入理解golang中的nil
#
nil is (a) zero
什么是零值(zero value)#
1
2
3
4
5
6
7
8
9
10
11
12
| // go中的零值
bool -> false
numbers -> 0
string -> ""
pointers -> nil // point to nothing
slices -> nil // have no backing array
maps -> nil // are not initialized
channels -> nil // are not initialized
functions -> nil // are not initialized
interfaces -> nil // have no value assigned, not even a nil pointer
|
struct中的零值(zero values)#
1
2
3
4
5
6
7
| type Person struct{
Age int
Name string
Friend []Person
}
var p Person // Person{0,"",nil}
|
nil 是什么类型(type)#
“nil is a predeclared identifier in Go that represents zero values for pointers, interfaces, channels, maps, slices and function types.”
nil 是 Go 中预先声明的标识符,表示指针、接口、通道、映射、切片和函数类型的零值。
一些关于nil
的实践#
1
2
3
4
| //nil == nil
var s fmt.Stringer // Stringer (nil,nil)
fmt.Println(s == nil) // true
|
1
2
3
| var p *Person // nil of type *Person
var s fmt.Stringer = p // Stringer(*Person,nil)
fmt.Println(s == nil) // false
|
nil not nil ?#
- Do not declare concrete error vars (不要声名错误变量)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // bad
type NameEmtpyError struct {
name string
}
// NameEmtpyError实现了 Error() 方法的对象
func (e *NameEmtpyError) Error() string {
return "name 不能为空"
}
func do() error {
var err *NameEmtpyError
return err // nil of type *NameEmtpyError
}
func main(){
err := do() // error(*NameEmtpyError,nil)
fmt.Println(err == nil) // false
}
|
1
2
3
4
5
6
7
8
9
10
11
12
| // bad
func do() *NameEmtpyError {
return nil // nil of type *NameEmtpyError
}
func wrapDo() error { // error(*NameEmtpyError, nil)
return do() // nil of type *NameEmtpyError
}
func main(){
err := wrapDo() // error(*NameEmtpyError,nil)
fmt.Println(err == nil) // false
}
|
nil is useful#
1
2
3
4
5
6
| pointers // methods can be callend on nil receivers 方法可以在 nil 接收器上调用
slices // perfectly valid zero values 完全有效的零值映射
maps // perfect as read-only values 完美的只读值
channels // essential for some concurrency patterns 对于某些并发模式必不可少
functions // needed for completeness 完整性所需
interfaces // the most userd signal in Go(err != nil) Go中使用次数最多的信号(err != nil)
|