首頁 >後端開發 >Golang >使用 Go 的「interface{}」和「json.Unmarshal」時,如何避免意外行為?

使用 Go 的「interface{}」和「json.Unmarshal」時,如何避免意外行為?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-21 08:06:12992瀏覽

How Can I Avoid Unexpected Behavior When Using Go's `interface{}` with `json.Unmarshal`?

Golang interface{} 類型誤解

使用interface{} 類型作為函數參數時,開發者經常會遇到意想不到的行為者,尤其是透過json.Unmarshal 與JSON 資料互動。

問題:

在 Go 中,interface{} 是一種可以保存任何值和類型的類型。然而,它通常被誤解為無類型容器。這種誤解會在以下情況下出現:

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    json.Unmarshal(j, &i)
    fmt.Println(i)
}

func main() {
    test(Test{})
}

預期行為:
此程式碼嘗試將 JSON 資料解組到測試結構中。但是,它會導致結構體意外轉換為 map[string]interface{} 類型。

解釋:

json.Unmarshal 無法將 JSON 解組為非指標值。由於 i 是一個持有 Test 結構的介面{},因此它作為位址 (&i) 傳遞以允許修改。但是,json.Unmarshal 將interface{} 指標視為指向包含Test 結構的interface{} 值的指標。無法解組為非指針,它預設為解組的 JSON 建立一個新的 map[string]interface{} 值。

正確的方法:

為了解決這個誤解,請考慮以下幾點場景:

func test(i *interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    json.Unmarshal(j, i)
    fmt.Println(*i)
}

func main() {
    var i *Test
    test(&i)
}

解釋:

  • 將指標傳遞給interface{}參數,有效地將指標包裝在interface{}中。
  • 在函數內部,取消引用interface{}指針並將其直接傳遞給json.Unmarshal.
  • 由於i 持有指向Test 結構的指針,因此json.Unmarshal 正確地將JSON資料解組到結構中。

結論:

interface{} 是一種可以保存任何值的類型,但它不僅僅是一個任何類型的佔位符。為了避免意外行為,在使用 interface{} 作為函數參數時,請正確處理指針,尤其是在 JSON 運算中。

以上是使用 Go 的「interface{}」和「json.Unmarshal」時,如何避免意外行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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