處理 JSON 資料時,有時需要僅修改特定值而不丟失現有結構。如果您不知道 JSON 物件的整個結構,這可能會很有挑戰性,因為 Go 的encoding/json 套件會截斷目標結構中未包含的欄位。
本文探討了一種利用常規結構組合的技術和 json.RawMessage 實現部分解碼和更新,且不會丟失未知資訊。
部分解碼的關鍵解碼是將整個JSON 資料保存在原始欄位(例如,map[string]json.RawMessage)中,並選擇性地將特定欄位解碼到結構中。它是這樣完成的:
import "encoding/json" 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 }
這裡,UnmarshalJSON 將整個 JSON 資料檢索到 c.raw,然後將 Space 欄位解組到 c.Space。
部分解碼 JSON 資料後,您可以將特定欄位修改為需要。
修改已知欄位後,您需要將更新的 Color 結構編組回 JSON。為了保留現有結構並避免截斷,您可以編寫自訂MarshalJSON 方法:
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) }
在MarshalJSON 中,您對修改後的Space 欄位進行編組,然後在執行最終編組之前將其嵌入到原始映射中。
該技術允許您修改 JSON 資料中的特定值而不丟失未知信息,使其適合適用於完整 JSON 結構不可用或可能發生更改的場景。
以上是如何在 Go 中間分解碼和更新 JSON 資料而不丟失未知欄位?的詳細內容。更多資訊請關注PHP中文網其他相關文章!