Go での部分的な JSON デコードと更新
特定のシナリオでは、JSON オブジェクトの特定の値のみをデコードして更新するときに一般的な問題が発生します特に完全なオブジェクト構造が不明な場合。 Go の標準エンコーディング/json パッケージでは、構造体で提供されていないフィールドが切り捨てられ、データ損失が発生します。
json.RawMessage を使用した解決策
この問題の解決策は次のとおりです。カスタム構造体と json.RawMessage を結合します。このアプローチにより、エンコード/デコード用にデータ全体を生のフィールドに保存できます。
Go の json.RawMessage タイプは、任意の JSON データを保持できる []byte 値です。これは、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)) }
Output
before: {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}} after: {"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}
このソリューションにより、特定の値のみをデコードして更新できます(この場合はスペース)、その他すべての不明なデータは JSON オブジェクト内に保持されます。このアプローチでは、出力内のキーの順序やインデントが保持されないことに注意することが重要です。
以上がGo で JSON オブジェクトを部分的にデコードして更新する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。