golang中的<code>nil</code>,很多人都誤以為與Java、PHP等程式設計語言中的null一樣。但是實際上Golang的niu複雜得多了,如果不信,那我們繼續往下閱讀。
<code>nil</code> 為預聲明的标示符,定義在<code>builtin/builtin.go</code>,
按照Go語言規範,任何類型在未初始化時都對應一個零值:布爾類型是false,整型是0,字元串是"",而指針、函數、interface、slice、channel和map的零值都是nil。
PS:這裡沒有說結構體struct的零值為nil,因為struct的零值與其屬性有關
<code>nil</code>沒有預設的類型,盡管它是多個類型的零值,必須顯式或隐式指定每個nil用法的明确類型。
如果關注過golang關鍵字的同學就會發現,裡面并沒有<code>nil</code>,也就是說<code>nil</code>并不是關鍵字,那麼就可以在代碼中定義<code>nil</code>,那麼<code>nil</code>就會被隐藏。
<code>nil</code>類型的所有值的記憶體布局始終相同,換一句話說就是:不同類型<code>nil</code>的記憶體位址是一樣的。
業務中一般将<code>nil</code>值表示為異常。nil值的大小始終與其類型與<code>nil</code>值相同的<code>non-nil</code>值大小相同。是以, 表示不同零值的nil辨別符可能具有不同的大小。
大小是編譯器和體系結構所依賴的。以上列印結果為64位體系結構和正式 Go 編譯器。對于32位體系結構, 列印的大小将是一半。
對于正式 Go 編譯器, 同一種類的不同類型的兩個nil值的大小始終相同。例如, 兩個不同的切片類型 ( []int和[]string) 的兩個nil值始終相同。
1.不同類型的<code>nil</code>是不能比較的。
在 Go 中, 兩個不同可比較類型的兩個值隻能在一個值可以隐式轉換為另一種類型的情況下進行比較。具體來說, 有兩個案例兩個不同的值可以比較:
兩個值之一的類型是另一個的基礎類型。
兩個值之一的類型實作了另一個值的類型 (必須是接口類型)。
<code>nil</code>值比較并沒有脫離上述規則。
2.同一類型的兩個<code>nil</code>值可能無法比較 因為golang中存在map、slice和函數類型是不可比較類型,它們有一個别稱為<code>不可比拟的類型</code>,是以比較它們的<code>nil</code>亦是非法的。
<code>不可比拟的類型</code>的值缺是可以與“純nil”進行比較。
3.兩<code>nil</code>值可能不相等
如果兩個比較的nil值之一是一個接口值, 而另一個不是, 假設它們是可比較的, 則比較結果總是 false。原因是在進行比較之前, 接口值将轉換為接口值的類型。轉換後的接口值具有具體的動态類型, 但其他接口值沒有。這就是為什麼比較結果總是錯誤的。
1.函數傳回
因為<code>error</code>是接口類型是以<code>error</code>類型沒有報錯。
2.map的nil key map的key為指針、函數、interface、slice、channel和map,則key可以為nil。
nil之是以比較難以了解因為我們經常混淆了nil值和nil類型,希望各位同學細細品味其中差別。
本文轉自 夢朝思夕 51CTO部落格,原文連結:http://blog.51cto.com/qiangmzsx/1980197