I've been trying to parse this JSON message from PubNub without any luck:
type PubNubMessage struct {
body []string
}
[[{"text":"hey"}],"1231212412423235","channelName"]
json: cannot unmarshal array into Go value of type main.PubNubMessage
Does anyone have an idea on how to decode such complex types in golang?
Your json is a heterogeneous array. You can at least define
PubNubMessage
as eithertype PubNubMessage []interface{}
and then access data with type assertionstext:= (message[0].([]interface {})[0].(map[string]interface {}))["text"].(string)
working example https://play.golang.org/p/xhwbE2ora1or
type PubNubMessage []json.RawMessage
and afterjson.Unmarshal(jsonBlob, &message)
do 'json.Unmarshal(message[0], structured.text)' for each peace separatelyhttps://play.golang.org/p/TJ0DfiweGo
The short answer is that you cannot directly unmarshal a JSON array of non-homogenous types (per your example) into a golang struct.
The long answer is that you should define an
(m *PubNubMessage) UnmarshalJSON([]byte) error
method for your PubNubMessage type which unmarshals the JSON string into aninterface{}
and then uses type assertions to ensure the expected format and populates the structure.For example:
You can define
UnmarshalJSON
on yourPubNubMessage
to provide custom JSON deserialization. You probably should tweak this a little bit for your purposes, but the general idea is that you just unmarshal this json array into a slice, and then get all necessary parts from it.Playground example here
It is easier to use alternative to
encoding/json
packages for parsing JSON arrays with values of distinct types. For instance, give a try to fastjson. It easily (and quickly) parses such arrays:Additionally
fastjson
provides handy functions for obtaining only the required fields from JSON: