首頁 >後端開發 >Golang >如何在 Go 中間分解碼和更新 JSON 物件?

如何在 Go 中間分解碼和更新 JSON 物件?

Barbara Streisand
Barbara Streisand原創
2024-12-25 00:29:16855瀏覽

How to Partially Decode and Update JSON Objects in Go?

Go 中的部分JSON 解碼和更新

在某些場景下,僅解碼和更新JSON 物件的特定值時會出現常見問題,特別是當完整的物件結構未知時。 Go中的標準encoding/json套件會截斷結構體中未提供的字段,導致資料遺失。

使用json.RawMessage的解決方案

這個問題的解決方案是將自訂結構與 json.RawMessage 結合。這種方法允許我們將整個資料保存到原始欄位中以進行編碼/解碼。

Go 中的 json.RawMessage 類型是一個 []byte 值,可以保存任意 JSON 資料。對於這樣的情況很有用,我們只知道 JSON 結構的一部分,並希望保留未知部分。

範例程式碼

package main

import (
    "encoding/json"
    "log"
)

type Color struct {
    Space string
    raw   map[string]json.RawMessage
}

func (c *Color) UnmarshalJSON(bytes []byte) error {
    if err := json.Unmarshal(bytes, &c.raw); err != nil {
        return err
    }
    if space, ok := c.raw["Space"]; ok {
        if err := json.Unmarshal(space, &c.Space); err != nil {
            return err
        }
    }
    return nil
}

func (c *Color) MarshalJSON() ([]byte, error) {
    bytes, err := json.Marshal(c.Space)
    if err != nil {
        return nil, err
    }
    c.raw["Space"] = json.RawMessage(bytes)
    return json.Marshal(c.raw)
}

func main() {
    before := []byte(`{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}`)
    log.Println("before: ", string(before))

    // decode
    color := new(Color)
    err := json.Unmarshal(before, color)
    if err != nil {
        log.Fatal(err)
    }

    // modify fields of interest
    color.Space = "RGB"

    // encode
    after, err := json.Marshal(color)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("after:  ", string(after))
}

輸出

before:  {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}
after:   {"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}

此解決方案允許我們僅解碼和更新特定值解碼和更新特定值解碼(在本例中為Space),同時保留JSON 物件中的所有其他未知資料。需要注意的是,這種方法不會保留輸出中的鍵順序或縮排。

以上是如何在 Go 中間分解碼和更新 JSON 物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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