Interface{} 類型誤解:揭示複雜性
在Go 中,interface{} 類型既提供了靈活性,也提供了複雜性。然而,誤解其本質可能會導致意想不到的後果,如一個令人費解的例子所示。
當嘗試將非指標類型作為 interface{} 參數傳遞給函數並使用 json.Unmarshal 時,輸出可能會令人驚訝。下面的範例示範了這種行為:
package main import ( "encoding/json" "fmt" ) func test(i interface{}) { j := []byte(`{ "foo": "bar" }`) fmt.Printf("%T\n", i) fmt.Printf("%T\n", &i) json.Unmarshal(j, &i) fmt.Printf("%T\n", i) } type Test struct { Foo string } func main() { test(Test{}) }
輸出:
main.Test *interface {} map[string]interface {}
揭開神秘面紗
混亂源自於介面的本質{}。它不僅僅是一個無類型容器,而是一個(值,類型)對的包裝器。此介面儲存對具體值及其類型的引用。
json.Unmarshal 將一個 interface{} 值作為其輸入,因此我們可以直接將 i 傳遞給它。嘗試取得其地址(與 &i 一樣)是不必要的。
指標和介面
但是,如果 i 包含非指標值,則 json.Unmarshal 面臨挑戰。由於套件無法解組為非指針,因此它會建立一個類型為interface{}的新值。這允許它選擇類型,預設為map[string]interface{}。
正確的場景
對於指標場景,傳遞&i 作為參數之所以有效,是因為json.Unmarshal 取消引用指標以尋找包含*Test 值的interface{ } 值。指標確保解組發生在正確的類型中。
結論
為了避免這些混淆,請避免使用指向介面的指標。相反,將指針“放置”在接口內並直接傳遞它們。透過了解 interface{} 和指標之間的相互作用,開發人員可以避免意外結果並有效利用 Go 的類型系統。
以上是為什麼使用非指標「interface{}」參數的「json.Unmarshal」會在 Go 中產生意外結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!