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

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

Mary-Kate Olsen
發布: 2024-12-04 20:19:12
原創
314 人瀏覽過

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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板