I have two structs. One inherits from the other.
type Animal struct {
Name string `json:"name"`
}
type Dog struct {
Animal
Color string `json:"color"`
}
When I go to Unmarshal
to Dog
by passing in:
{
"name": "Loki",
"color": "Brown"
}
I'm getting an *encoding/json.InvalidUnmarshalError
. 2019/03/10 00:22:35 json: Unmarshal(nil *main.Dog)
Why is that?
Here's the unmarshal code:
func main() {
var dog *Dog
err := json.Unmarshal([]byte(`{
"name": "Loki",
"color": "Brown"
}`), dog)
if err != nil {
log.Fatal(err)
}
}
That's because the variable dog
is nil. Try to initialize it to point to an empty Dog
. Or make it a Dog
instead of a pointer to Dog
and pass in the address to Unmarshal
.
First of all, to get the concepts straight -- there's no inheritance in Golang. Golang prefers composition over inheritance. What you're doing with Animal
and Dog
there is called embedding in Go.
Secondly, the correct way to use json.Unmarshal
is to pass a pointer as the second argument. So, to fix your code:
func main() {
var dog Dog
err := json.Unmarshal([]byte(`{
"name": "Loki",
"color": "Brown"
}`), &dog)
if err != nil {
log.Fatal(err)
}
}
If you're familiar with C, think of json.Unmarshal
as something similar to scanf
. The caller pass an address to scanf
so that scanf
can "fill in the value" to the memory location represented by the pointer.