JSON をインターフェースにアンマーシャリングする方法を理解することは、Go 開発者にとって重要なスキルです。この記事では、JSON をインターフェース フィールドを持つ構造体にアンマーシャリングすることに関連する落とし穴と解決策を示す実践的な例を説明します。
次の型定義について考えてみましょう。
type Message struct { Cmd string `json:"cmd"` Data interface{} `json:"data"` } type CreateMessage struct { Conf map[string]int `json:"conf"` Info map[string]int `json:"info"` }
作成メッセージを表す JSON 文字列が与えられると、それをメッセージにデコードしようとする可能性がありますstruct:
{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}
import "encoding/json" var data = []byte(`{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}`) var m Message if err := json.Unmarshal(data, &m); err != nil { log.Fatal(err) }
アンマーシャリングされたメッセージ構造体を調べると、データ フィールドがマップ[文字列]インターフェイスとして残っていることがわかります。{}:
{Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}
この制限を克服するために、2 つの方法を採用しています。アプローチ:
type Message struct { Cmd string `json:"cmd"` Data json.RawMessage } type CreateMessage struct { Conf map[string]int `json:"conf"` Info map[string]int `json:"info"` }
これらの変更により、次のコマンドに基づいてバリアント データを適切な構造体タイプにデコードできます。
func main() { var m Message if err := json.Unmarshal(data, &m); err != nil { log.Fatal(err) } switch m.Cmd { case "create": var cm CreateMessage if err := json.Unmarshal([]byte(m.Data), &cm); err != nil { log.Fatal(err) } fmt.Println(m.Cmd, cm.Conf, cm.Info) default: log.Fatal("bad command") } }
この手法を採用することで、次のことが可能になります。 JSON データが Message 構造体に正常にアンマーシャリングされます。Data フィールドにはバリアント CreateMessage タイプが含まれます。完全な実装については、提供されているプレイグラウンドの例を参照してください。
以上がJSON を Go のインターフェースに効果的にアンマーシャリングする方法{}の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。