深入理解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)