Go 介面中 Nil 切片的特殊行為
在 Go 中,切片可以被賦予 nil 值,這表示一個空切片。然而,當將 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 切片作為它們的參數。但是,兩個函數的輸出不同。 yes 列印 true,表示切片確實為零。不,另一方面,印 false。
為什麼會出現這種差異?答案在於 Go 介面內部表示 nil 切片的方式。
interface{} 變數用於表示各種類型,由兩個欄位組成:類型和資料指標。當一個 nil 切片傳遞給需要一個 interface{} 的函數時,它會被包裝在一個 interface{} 類型中,並且資料指標被設定為 nil。
在 yes 的情況下,它直接比較nil 的參數,有效地詢問切片本身是否為零。此比較傳回 true,因為切片確實為空。
但是,no 函數接收包裝在 interface{} 中的 nil 切片。這種情況下的比較不僅僅是切片和 nil 之間的比較,而是整個 interface{} 和 nil 之間的比較。在運行時內部,這種比較歸結為測試 interface{} 的資料指標是否為 nil,這是 false,因為介麵包裝器已為其分配了記憶體。
此行為也記錄在Go 的常見問題解答中:
「將nil 切片傳遞給介面的一個常見問題:由於nil 切片由nil 介面值表示,因此在測試介面i (nil 介面)的值時寫入if i == nil 可能會虛假成功是假的)。
以上是為什麼 Nil 切片在傳遞到 Go 中的介面時表現不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!