Proper way to unmarshal a JSON null value

8,261 views
Skip to first unread message

Ji H Park

unread,
Oct 1, 2012, 10:31:25 PM10/1/12
to golan...@googlegroups.com
Hi, I've been looking to find a proper way to unmarshal a JSON null value.

Whenever I try unmarshalling a JSON blob containing a null value, the following message is showed:

"error: json: cannot unmarshal null into Go value of type string"

As you can see on the error, I'm expecting a string value.

To see what else could work, I went through the spec and found that all types implement the empty interface "interface {}".

So instead I made the variable type arbitrary using interface{}.

I wasn't so sure though, I'm still skeptical about using "interface{}".

Is there a proper way to unmarshal a JSON null value?

I would appreciate your help! Thanks!

Here is the code: http://pastie.org/4894381

jorelli

unread,
Oct 1, 2012, 11:03:35 PM10/1/12
to golan...@googlegroups.com
the reason that this error occurs is that, technically, a string cannot be null; the zero value for a string is the empty string.  You cannot assign a string to nil.

However, there are two solutions to this problem:

    use *string instead of string
    define your own nullable string type and unmarshal null to empty string

The first solution is simply to turn your LastName field into a *string.  The result is that now you have the possibility of encountering null pointers, but you're actually accurately modeling the information.  This is the most "purely correct" way of doing things, but can lead to runtime panics if you're not checking for nil pointers every time you want someone's last name.

Sometimes it's better to just screw the accuracy and do the thing that's more comfortable with your application, especially if you're dealing with some input that you know is dirty and you're going to be transforming it anyway.

You can define a nullable string type, NString, with the semantics of "if the JSON says null, replace it with empty string", as follows:

type Nstring string

func (n *Nstring) UnmarshalJSON(b []byte) (err error) {
if string(b) == "null" {
return nil
}
return json.Unmarshal(b, (*string)(n))
}

see here for an example: http://play.golang.org/p/LpFTzhkszU

of course, now you have to convert to string all over the place.  Be aware that, yes, this is throwing away information since we now lose the ability to differentiate between null and empty string in the source input; that may or may not matter to you.

So... you're stuck either converting to string or checking for nil pointers.

Henrik Johansson

unread,
Oct 2, 2012, 1:31:33 AM10/2/12
to jorelli, golan...@googlegroups.com

There is an issue about this but i cant find it on my phone unfortunately. It got accepted but without eta.

--
 
 
Reply all
Reply to author
Forward
0 new messages