Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does json.Unmarshal work with reference but not pointer?

Tags:

json

go

This example from the json.Unmarshal docs (slightly modified for simplicity to use Animal instead of []Animal) works, no errors:

Playground link of working example

// ... var animals Animal err := json.Unmarshal(jsonBlob, &animals) // ... 

But this slightly modified example doesn't:

Playground link of non-working example

// ... var animals *Animal err := json.Unmarshal(jsonBlob, animals) // ... 

It displays this obscure error that really isn't helpful (looks more like a function call than an error IMO):

json: Unmarshal(nil *main.Animal)

This appears to be because animals is an uninitialized pointer. But the docs say (emphasis mine):

Unmarshal unmarshals the JSON into the value pointed at by the pointer. If the pointer is nil, Unmarshal allocates a new value for it to point to.

So why does unmarshaling fail in the second example and show that obscure error?

(Also, is it "unmarshalling" or "unmarshaling" (one L)? The docs use both.)

like image 261
Matt Avatar asked Dec 09 '13 19:12

Matt


People also ask

How does JSON Unmarshal work?

To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.

What does Unmarshal work on *?

Unmarshal is the contrary of marshal. It allows you to convert byte data into the original data structure. In go, unmarshaling is handled by the json. Unmarshal() method.

What is JSON Marshal Unmarshal?

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.

What is Unmarshal go?

Un-marshalling in GOLANG json. Unmarshal() method help to convert json(Byte data) into Struct Object, This method takes json byte data as a param and returned struct object.


2 Answers

You've encountered an InvalidUnmarshalError (see lines 109 and 110 in decode.go).

// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
// (The argument to Unmarshal must be a non-nil pointer.)

It seems the docs could do with some clarification as the quote above and the comment below from the Unmarshal source seem to contradict each other.

If the pointer is nil, Unmarshal allocates a new value for it to point to.

like image 86
Intermernet Avatar answered Oct 17 '22 12:10

Intermernet


Because your pointer is nil.

If you initialize it it works: http://play.golang.org/p/zprmV0O1fG

var animals *Animal = &Animal{} 

Also, it can be spelled either way (consistency in a single doc would be nice, though): http://en.wikipedia.org/wiki/Marshalling_(computer_science)

like image 37
Eve Freeman Avatar answered Oct 17 '22 12:10

Eve Freeman