JSON データを操作する場合、既存の構造を失わずに特定の値のみを変更する必要がある場合があります。 Go のエンコーディング/json パッケージでは、ターゲットの構造体に含まれていないフィールドが切り捨てられるため、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 中国語 Web サイトの他の関連記事を参照してください。