首頁 >後端開發 >Golang >為什麼使用非指標「interface{}」參數的「json.Unmarshal」會在 Go 中產生意外結果?

為什麼使用非指標「interface{}」參數的「json.Unmarshal」會在 Go 中產生意外結果?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-04 20:19:12267瀏覽

Why Does `json.Unmarshal` with a Non-Pointer `interface{}` Parameter Produce Unexpected Results in Go?

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn