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