Go語言 nil的介紹

2018-07-25 17:23 更新

nil的語義

什么?nil是一種數(shù)據(jù)結(jié)構(gòu)么?為什么會講到它,沒搞錯吧?沒搞錯。不僅僅是Go語言中,每門語言中nil都是非常重要的,它代表的是空值的語義。

在不同語言中,表示空這個概念都有細微不同。比如在scheme語言(一種lisp方言)中,nil是true的!而在ruby語言中,一切都是對象,連nil也是一個對象!在C中NULL跟0是等價的。

按照Go語言規(guī)范,任何類型在未初始化時都對應(yīng)一個零值:布爾類型是false,整型是0,字符串是"",而指針,函數(shù),interface,slice,channel和map的零值都是nil。

interface

一個interface在沒有進行初始化時,對應(yīng)的值是nil。也就是說var v interface{},

此時v就是一個nil。在底層存儲上,它是一個空指針。與之不同的情況是,interface值為空。比如:

var v *T
var i interface{}
i = v

此時i是一個interface,它的值是nil,但它自身不為nil。

Go中的error其實就是一個實現(xiàn)了Error方法的接口:

type error interface {
    Error() string
}

因此,我們可以自定義一個error:

type Error struct {
    errCode uint8
}
func (e *Error) Error() string {
        switch e.errCode {
        case 1:
                return "file not found"
        case 2:
                return "time out"
        case 3:
                return "permission denied"
        default:
                return "unknown error"
         }
}

如果我們這樣使用它:

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}
var e *Error
checkError(e)

e是nil的,但是當(dāng)我們checkError時就會panic。請讀者思考一下為什么?

總之,interface跟C語言的指針一樣非常靈活,關(guān)于空的語義,也跟空指針一樣容易困擾新手的,需要注意。

string和slice

string的空值是"",它是不能跟nil比較的。即使是空的string,它的大小也是兩個機器字長的。slice也類似,它的空值并不是一個空指針,而是結(jié)構(gòu)體中的指針域為空,空的slice的大小也是三個機器字長的。

channel和map

channel跟string或slice有些不同,它在棧上只是一個指針,實際的數(shù)據(jù)都是由指針所指向的堆上面。

跟channel相關(guān)的操作有:初始化/讀/寫/關(guān)閉。channel未初始化值就是nil,未初始化的channel是不能使用的。下面是一些操作規(guī)則:

  • 讀或者寫一個nil的channel的操作會永遠阻塞。
  • 讀一個關(guān)閉的channel會立刻返回一個channel元素類型的零值。
  • 寫一個關(guān)閉的channel會導(dǎo)致panic。

map也是指針,實際數(shù)據(jù)在堆中,未初始化的值是nil。

links


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號