Unmarshalling JSON in Go Without Double Unmarshaling
In Go, it's possible to face a situation where you need to parse JSON into various structs, but double unmarshalling occurs, leading to redundancy. This article presents a solution that involves partially unmarshalling the data to avoid the second unmarshaling step.
Understanding the Issue
When attempting to parse JSON into known structs, a common approach is:
The Solution
Instead of casting the value to an interface{}, one can unmarshal it into a json.RawMessage. This partially unmarshals the data and allows subsequent unmarshalling to specific structs based on the key value.
Sample Code
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) } jsonAck, ok := myMap["ack"] if !ok { fmt.Println("key 'ack' not found") return } err = json.Unmarshal(jsonAck, &myAck) if err != nil { fmt.Println("unmarshal error", err) } else { fmt.Println("New ack object: ", myAck) } }
In this modified code, we replace the map[string]interface{} with map[string]json.RawMessage. When handling the "ack" key, we unmarshal directly to the Ack struct, eliminating the need for double unmarshalling.
The above is the detailed content of How to Avoid Double Unmarshaling When Parsing JSON in Go?. For more information, please follow other related articles on the PHP Chinese website!