JSON データを操作する場合、オブジェクトの完全な構造を持たずに特定の値にアクセスして変更する必要があることがよくあります。 。 Go のエンコーディング/json パッケージは、堅牢なデコーディングおよびエンコーディング機能を提供しますが、宛先構造体で明示的に定義されていないフィールドは切り捨てられるか無視されます。これにより、再エンコード時に不明な情報が失われる可能性があります。
この課題を克服するには、通常の構造体と json を組み合わせて利用できます。 RawMessage を使用して部分的なデコードと更新を実現します。 json.RawMessage は生の JSON データを表し、特定の形式をデコードせずに任意の JSON 構造を保持できるようにします。
次のコード スニペットでは、Color 構造体が Space フィールドと、map 型の raw フィールドで定義されています[文字列]json.RawMessage.これにより、既知のフィールド (Space) のみを明示的にアンマーシャリングしながら、JSON オブジェクト全体を保存できるようになります。
type Color struct { Space string raw map[string]json.RawMessage }
アンマーシャリング プロセス中に、UnmarshalJSON メソッドは Space フィールドを抽出します。生データが存在する場合、そのデータから。完全な生データは生マップに保存されます。
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 }
値を更新するときは、既知のフィールドのみを変更する必要があります。この場合、color.Space に新しい値を割り当てることができます。
マーシャリング中、MarshalJSON メソッドは更新されたスペース値を取得し、生のマップに json.RawMessage として保存します。オブジェクト全体を JSON としてエンコードします。
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) }
以下この例は、JSON オブジェクトの部分的なデコードと更新を示しています。
before := []byte(`{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}`) // Decode color := new(Color) err := json.Unmarshal(before, color) // Modify the Space field color.Space = "RGB" // Encode after, err := json.Marshal(color)
出力は次のようになります。
{"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}
このアプローチでは、未知の構造と情報が保存され、部分的なデコードと更新が可能になります。 JSON オブジェクトの数。
以上が未知の情報を失わずに Go で JSON データを部分的にデコードして更新するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。