問題ステートメント
Go の json.Unmarshal を使用して文字列をデコードする場合メッセージ システムから、結果は、代わりに、map[string]interface{} であることがわかります。予期された構造体の型 (Somthing1 または Somthing2) により、型アサーションが不可能になります。
根本原因
インターフェイスにアンマーシャリングするときの json.Unmarshal 関数は、デフォルトです。{} []interface{} や map[string]interface{} などの既知のタイプに変換します。指定されたコードでは、インターフェース変数 input はアンマーシャリングされた JSON データを表す map[string]interface{} を受け取りますが、switch ステートメントはそれを Somthing1 または Somthing2 として直接アサートしようとします。
Solution
JSON は目的の構造体にネイティブにアンマーシャリングされないため、これに対処するには 2 つのオプションがあります問題:
1.ジェネリック マップからの検査と変換:
1 つの方法は、map[string]interface{} を検査し、データを適切な構造体タイプに手動で解凍することです。ただし、これには潜在的なエラーを慎重に処理し、値を手動で割り当てる必要があります。
2.カスタム JSON アンマーシャラーを利用する:
よりクリーンな解決策は、アンマーシャリング プロセスを処理するカスタム JSON アンマーシャラーを作成することです。このカスタム アンマーシャラーは、JSON データに基づいて正しい構造体型を識別し、それに応じてアンマーシャリングできます。このようなアンマーシャラーの例を次に示します。
type Unpacker struct { Data interface{} } func (u *Unpacker) UnmarshalJSON(b []byte) error { smth1 := &Something1{} err := json.Unmarshal(b, smth1) // no error, but we also need to make sure we unmarshaled something if err == nil && smth1.Thing != "" { u.Data = smth1 return nil } // abort if we have an error other than the wrong type if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok { return err } smth2 := &Something2{} err = json.Unmarshal(b, smth2) if err != nil { return err } u.Data = smth2 return nil }
このカスタム アンマーシャラーのインスタンスを json.Unmarshal に渡すと、結果の Data フィールドには正しい構造体型でアンマーシャリングされたデータが含まれ、シームレスな型アサーションが可能になります。 .
以上がGo の「json.Unmarshal」を「interface{}」で使用する場合、JSON データを特定の構造体に効率的にアンマーシャルするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。