前言
还剩下两个小时才能下班,看着时间一分一秒的过去,感觉有点罪恶感,为了不让自己有太深的罪恶感,那么我就再来一篇文章。
摸鱼的日子都是那么的枯燥无味......
Go中的nil
单词nil的意思就是“零”或者是“无”的意思,在Go中,nil所代表的就是一个零值。
在Go语言中,如果我们把声明了一个变量,但是却没有给它赋值,那么这个变量就是一个“零”,例如当我们声明了一个整数int。
var a int
fmt.Printf("this is a %v",a) // this is a 0
而字符串在同样的情况下,默认的是空字符。诸如此类,如果一个指针没有明确的指向的时候,它的值同样也是个nil。
在Go中,nil的使用还是非常的友好的,具体原因我会在下面说明。
指向nil的指针
我们知道,当一个指针没有一个明确的指向的时候,它就是nil,而程序如果去解引用一个nil指针的话,就会导致程序的奔溃。
var a * int
fmt.Println(a) // nil
fmt.Println(*a)
// panic: runtime error: invalid memory address or nil pointer dereference
而要避免这种情况的出现,其实也非常的简单,只需要在对指针进行解引用的时候,加一个判断就可以了
type person struct {
num int
}
func (p *person) change() {
if p == nil {
return
}
p.num++
}
func main() {
p := person{10}
p.change()
fmt.Printf("this is num %+v",p)
// this is num {num:11}
}
在Go语言里面,对于nil的处理将有开发者自己里决定,是要返回零值或者是一个错误类型,亦或者是直接让程序panic也是可以的。
nil的切片,以及映射
在声明了一个切片或者是映射的时候,如果没有使用复合字面量或者是内置的make函数去对它进行初始化的话,那么它同样值也会是一个nil.
var a []int
fmt.Print(a == nil) // true
在前面有提到,如果去操作一个nil,程序是会报错的,但是比较好的是,我们常用来处理切片或者映射的三个函数,append,len,ranger都有方法可以内置的处理这个nil的值
var a []int
fmt.Print(a == nil) // true
for v := range a{
fmt.Print(v)
}
fmt.Print(len(a)) //0
a = append(a, 1,2,3,4)
fmt.Print(a) // [1,2,3,4]
最后
虽然说nil有些时候使用的时候会有一些问题,但是在一些特殊情况还是一定作用的,例如在使用select的时候,这一点我会在后续其它文章中说明,今天就先聊到这里。
到点下班,溜溜球🪀!!!