前言
按照Go语言规范,任何类型在未初始化时都对应一个零值:
布尔类型是false,整型是0,字符串是””
而指针、函数、interface、slice、c**hannel和map的零值都是nil**
nil Go中是一个预先声明的标识符
您可以在nil不声明的情况下使用它。nil 可以表示多种类型的零值
在Go中,nil可以表示以下类型的零值:- pointer types (including type-unsafe ones).
- map types.
- slice types.
- function types.
- channel types.
- interface types.
package mainimport "fmt"type Person struct {Id intName stringInfo interface{}}func main() {var p Personfmt.Println(p)// {0 <nil>}}
nil 使用场景
pointers
nil pointer- 指向 nil, 又名 nothing
- pointer 的零值
指针表示指向内存的地址,如果对 nil 的指针进行解引用的话就会导致 panic。那么为 nil 的指针有什么用呢? 先来看看一个计算二叉树和的例子:
var p *int // 声明一个 int 类型的指针println(p) // <nil>p == nil // true*p // panic: runtime error: invalid memory address or nil pointer dereference
func (t *tree) Sum() int {if t == nil {return 0}return t.v + t.l.Sum() + t.r.Sum()}
slices
一个为nil的slice,除了不能索引外,其他的操作都是可以的,slice有三个元素,分别是长度、容量、指向数组的指针,当你需要填充值的时候可以使用append函数,slice会自动进行扩充。所以我们并不需要担心slice的大小,使用append的话slice会自动扩容。
// nil slicesvar s []Tlen(s) // 0cap(s) // 0for range s {} // iterates zero timess[i] // panic: index out of range
var s []intfor i := 0; i < 10; i++ {fmt.Printf("len: %2d cap: %2d\n", len(s), cap(s))s = append(s, i)}
