前言
按照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 main
import "fmt"
type Person struct {
Id int
Name string
Info interface{}
}
func main() {
var p Person
fmt.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 slices
var s []T
len(s) // 0
cap(s) // 0
for range s {
} // iterates zero times
s[i] // panic: index out of range
var s []int
for i := 0; i < 10; i++ {
fmt.Printf("len: %2d cap: %2d\n", len(s), cap(s))
s = append(s, i)
}