关于nil的纷扰 |Go 主题月

1,056 阅读2分钟

前言

还剩下两个小时才能下班,看着时间一分一秒的过去,感觉有点罪恶感,为了不让自己有太深的罪恶感,那么我就再来一篇文章。

摸鱼的日子都是那么的枯燥无味......

20190405192723670FMP.png

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的时候,这一点我会在后续其它文章中说明,今天就先聊到这里。

到点下班,溜溜球🪀!!!

下载 (1).jpeg