介面類型和nil 切片
在Go 中,當變數傳遞給需要介面類型的函數時,行為可能會有所不同判斷變數是否為切片。
考慮以下程式碼片段:
<code class="go">package main import "fmt" func main() { var i []int = nil yes(i) // output: true no(i) // output: false } func yes(thing []int) { fmt.Println(thing == nil) } func no(thing interface{}) { fmt.Println(thing == nil) }</code>
在此程式中,yes 函數需要一個整數切片,而 no 函數需要一個介面類型。當我們用 nil 切片 i 呼叫 yes 時,輸出為 true,因為切片本身為 nil。然而,使用 nil 切片呼叫 no 會導致 false。
要理解為什麼會發生這種情況,我們需要深入研究 Go 中介面的實作。在內部,介面類型表示為包含兩個欄位的結構體:Itab(指類型描述符)和 Data(保存實際值)。
將 nil 切片傳遞給 yes 時,僅包含 nil 值作為 Data 傳遞,比較實際上變成 nil == nil,這是正確的。然而,當將 nil 切片傳遞給 no 時,Go 會自動將其包裝在介面類型中,導致類似 no(interface{[]int, nil}) 的結果。在這種情況下,比較就變成了interface{[]int, nil} == nil,它傳回false,因為介面類型本身不為nil,即使底層資料為nil。
這種行為可以歸因於介面的本質以及它們如何與零值互動。如 Go FAQ 所解釋的,nil 介面和 nil 具體值是不同的概念。當介面類型持有 nil 值時,並不表示介面本身就是 nil。因此,將包含 nil 值的介面類型與 nil 進行比較將會得到 false。
以上是為什麼 Go 中的具體類型和介面之間的 Nil 切片與「nil」的比較有所不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!