在Go 中,處理JSON 資料時,有時需要部分解組資料以存取未知欄位或處理異構JSON 結構。但是,此過程可能會導致雙重解組,從而效率低下。本文提出了一種使用 json.RawMessage 來避免此問題的解決方案。
考慮這樣一個場景:Web 套接字連接發送不同類型的 JSON 訊息,並且您希望將它們解組到已知的結構中。傳統方法包括將 JSON 解組為通用的 map[string]interface{},搜尋所需的鍵,然後嘗試將值轉換為所需的類型。但是,在使用巢狀 JSON 結構時,此方法可能會失敗。
要解決此問題,我們可以將它們解組到 json.RawMessage,而不是將值解組到 interface{}。這使我們能夠存取原始 JSON 資料而不會遺失類型資訊。稍後,在 switch 語句中,我們可以直接將原始 JSON 資料解組到所需的結構中,而無需重新編組。
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 數據,使得處理異質結構的 JSON 數據更加高效、簡單。
以上是在處理異質 JSON 結構時,json.RawMessage 如何防止 Go 中的雙重解組?的詳細內容。更多資訊請關注PHP中文網其他相關文章!