處理包含不同類型資料的JSON 訊息時,常見的方法可能涉及將資料解組到通用映射中[ string]interface{} 檢查鍵並嘗試將值轉換為特定結構。然而,這種方法可能會導致不必要的雙重解組。
在 Go 上下文中,有一個更有效的解決方案可以將 JSON 資料部分解組到 json.RawMessage 而不是 interface{}。這是透過將映射聲明為:
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中文網其他相關文章!