さまざまな種類のデータを含む JSON メッセージを処理する場合、一般的なアプローチには、データを汎用マップにアンマーシャリングすることが含まれる場合があります[ string]interface{} を使用してキーを検査し、値を特定の構造体にキャストしようとします。ただし、このアプローチでは、不必要な二重アンマーシャリングが発生する可能性があります。
Go のコンテキストでは、JSON データを Interface{} の代わりに json.RawMessage に部分的にアンマーシャリングする、より効率的なソリューションがあります。これは、マップを次のように宣言することで実現されます。
var myMap map[string]json.RawMessage
値を特定の構造体にキャストする場合、マーシャリング/アンマーシャリングのステップを省略できます。たとえば、あなたの場合、次を使用して "Ack" 構造体にキャストしていました:
ackjson, err := json.Marshal(v) if err != nil { fmt.Println("marshal error: ", err) } err = json.Unmarshal(ackjson, &myAck) if err != nil { fmt.Println("unmarshal error", err) }
代わりに、次のように簡略化できます:
err = json.Unmarshal(v, &myAck)
このアプローチでは、冗長なアンマーシャリングが回避されます。
これを組み込んだコードの更新バージョンを次に示します。最適化:
package main import ( "encoding/json" "fmt" ) type Ping struct { Ping string `json:"ping"` } type Ack struct { Messages []Message `json:"messages"` } type Message string func main() { testJSON := []byte(`{"ack":{"messages":["Hi there","Hi again"]}}`) var myAck = Ack{} var myMap map[string]json.RawMessage err := json.Unmarshal(testJSON, &myMap) if err != nil { fmt.Println("error unmarshalling: ", err) } for k, v := range myMap { fmt.Printf("key: %s, value: %s \n", k, v) switch k { case "ping": fmt.Println(k, " is a ping", v) case "ack": fmt.Println(k, " is an ack containing a message list") err = json.Unmarshal(v, &myAck) if err != nil { fmt.Println("unmarshal error", err) } else { fmt.Println("New ack object: ", myAck) } default: fmt.Printf("%s is of a type (%T) I don't know how to handle", k, v) } } }
json.RawMessage を利用し、不必要なアンマーシャリングを排除することで、機能を損なうことなく JSON 解析のパフォーマンスを向上させることができます。
以上が冗長なアンマーシャリングを行わずに Go で JSON を効率的に解析するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。