Why does this fail with the error :
json: cannot unmarshal object into Go struct field Person.spouse of type main.Spouse
type Spouse interface {
Name() // Adding this causes an error
}
type Address interface {
}
type Person struct {
Name string `json:"name"`
A *Address `json:"address"`
S *Spouse `json:"spouse"`
}
func main() {
b := []byte(`{
"name":"sarah",
"address":{
"street":"101 main"
},
"spouse":{
"name":"joe"
}
}
`)
p := &Person{}
if err := json.Unmarshal(b, p); err != nil {
fmt.Printf("%s", err)
}
}
Looking at the docs, I don't see why adding a function in an interface would cause an error. I was expecting json.Unmarshal to simply ignore the Name() function since it's not part of the list processed by json.Unmarshal.
Here is the code in go playground.
go version go1.10 darwin/amd64
From the fine manual:
func Unmarshal
[...]
To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:bool, for JSON booleans float64, for JSON numbers string, for JSON strings []interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null
You're trying to unmarshal a JSON object into an interface so the value behind that interface is going to be a map[string]interface{}
to represent the key/value pairs. But map[string]interface{}
doesn't have a Name()
method so it doesn't implement your Spouse
interface.
If we simplify your example a little and get rid of the Name()
method we can see what's going on:
type Spouse interface {
}
type Person struct {
S *Spouse `json:"spouse"`
}
func main() {
b := []byte(`{"spouse":{ "name":"joe" } }`)
p := &Person{}
if err := json.Unmarshal(b, p); err != nil {
fmt.Printf("%s", err)
}
spouse := (*p.S).(map[string]interface{})
fmt.Printf("%+v\n", spouse)
}
spouse
is a map[string]interface{}
as documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With