I'm a newbie in Go and now I have a problem. I have a type called Message, it is a struct like this:
type Message struct { Cmd string `json:"cmd"` Data interface{} `json:"data"` }
I also have a type called CreateMessage like this:
type CreateMessage struct { Conf map[string]int `json:"conf"` Info map[string]int `json:"info"` }
And I have a JSON string like {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}
.
When I use json.Unmarshal
to decode that into a Message variable, the answer is {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}
.
So could I decode the JSON into a Message struct and change its Data's interface{} to type CreateMessage according to the Cmd?
I tried to convert Data directly into type CreateMessage but the complier told me that Data is a map[sting]interface{} type.
To parse JSON, we use the Unmarshal() function in package encoding/json to unpack or decode the data from JSON to a struct. Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. Note: If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
Golang Unmarshal It allows you to convert byte data into the original data structure. In go, unmarshaling is handled by the json. Unmarshal() method.
Generally, encoding/decoding JSON refers to the process of actually reading/writing the character data to a string or binary form. Marshaling/Unmarshaling refers to the process of mapping JSON types from and to Go data types and primitives.
Define a struct type for the fixed part of the message with a json.RawMessage field to capture the variant part of the message. Define struct types for each of the variant types and decode to them based on the the command.
type Message struct { Cmd string `json:"cmd"` Data json.RawMessage } type CreateMessage struct { Conf map[string]int `json:"conf"` Info map[string]int `json:"info"` } func main() { var m Message if err := json.Unmarshal(data, &m); err != nil { log.Fatal(err) } switch m.Cmd { case "create": var cm CreateMessage if err := json.Unmarshal([]byte(m.Data), &cm); err != nil { log.Fatal(err) } fmt.Println(m.Cmd, cm.Conf, cm.Info) default: log.Fatal("bad command") } }
playground example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With