このシナリオでは、JSON 文字列は RabbitMQ 経由で送信されます。これらの文字列は、Somthing1 と Somthing2 という 2 つの異なる構造体のインスタンスを表します。目標は、JSON 文字列をそれぞれの構造体にアンマーシャリングして戻し、型アサーションを実行することです。
一見すると、インターフェースにアンマーシャリングしてから型アサーションを適用するように見えます。{}十分なはずです。ただし、アンマーシャリングすると、入力変数の型は map[string]interface{} になります。これは予期したものではなく、この型をオンにするか、目的の構造体に再割り当てしようとすると失敗します。
Golang の JSON ライブラリは、bool、float64 などのデフォルトの型にアンマーシャリングされます。 、およびマップ[文字列]インターフェイス{}。目的の構造体を取得するには、構造体に直接アンマーシャリングするか、map[string] インターフェース{}から手動で変換する必要があります。
推奨されるアプローチは、構造体に直接アンマーシャリングすることです。構造体:
func typeAssert(msg string) { var job Somthing1 json.Unmarshal([]byte(msg), &job) // ... var stats Somthing2 json.Unmarshal([]byte(msg), &stats) // ... }
直接アンマーシャリングが不可能な場合は、Unpacker 構造体を使用してアンマーシャリングを処理し、データにアクセスするためのインターフェイスを提供できます。
type Unpacker struct { Data interface{} } func (u *Unpacker) UnmarshalJSON(b []byte) error { // Attempt to unmarshal into both types smth1 := &Something1{} err := json.Unmarshal(b, smth1) if err == nil && smth1.Thing != "" { u.Data = smth1 return nil } smth2 := &Something2{} err = json.Unmarshal(b, smth2) if err != nil { return err } u.Data = smth2 return nil }
その後、Unpacker を使用して次のことを行うことができます。非整列データにアクセスします:
func typeAssert(msg string) { unpacker := &Unpacker{} json.Unmarshal([]byte(msg), unpacker) switch v := unpacker.Data.(type) { case Something1: // ... case Something2: // ... default: // Handle unknown type } }
以上がGo で JSON をインターフェースにアンマーシャリングした後、型アサーションを効率的に処理するにはどうすればよいですか?{}の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。