Jens Alfke
unread,Mar 11, 2013, 5:05:27 PM3/11/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to golan...@googlegroups.com
So, I’ve got a custom type based on a map:
type Set map[string]struct{}
I’ve implemented JSON marshaling/unmarshaling for it, so it can be stored in JSON as an array of strings:
func (set Set) MarshalJSON() ([]byte, error) {…}
func (set Set) UnmarshalJSON(data []byte) error { … }
Now I can unmarshal JSON into a struct containing a Set:
type Data struct {
Names Set
}
var data Data
json.Unmarshal(jsonBytes, &data) // crash!
Unfortunately this fails with a null-pointer exception down in the UnmarshalJSON method, because the JSON decoder calls that method with a receiver (the ‘set’ variable) that’s nil. So when UnmarshalJSON tries to store a value into it, it crashes.
Is this a bug in the JSON package?
I can’t find any good workaround.
* There’s nothing I can do inside the UnmarshalJSON method, because even if I instantiate a map in it, there’s no way to pass that back to the caller, so it’s lost.
* I can pre-initialize the struct member, i.e. by adding “data.Names = Set{}” before the Unmarshal call. This leads to the correct result. But it’s awkward having to pre-initialize the unmarshaled object, and worse, now I have no way to detect whether the JSON contains a “names” field at all, since data.Names will never be nil after the unmarshaling.
–Jens