Why does json.Unmarshal return a map instead of the expected struct?
go, json, unmarshalling
Solution
You've passed to `json` a pointer to an abstract interface. You should simply pass a pointer to `Ping` as an abstract interface:
func bad() {
var ping interface{} = &Ping{} // <<<< this
deserialize([]byte(`{"id":42}`), ping) // << and this
fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why?
}
But if as you said you don't have a pointer to cast ton an `interface{}`, you can use reflect to create a new pointer, deserialize into it, and copy the value back:
func bad() {
var ping interface{} = Ping{}
nptr := reflect.New(reflect.TypeOf(ping))
deserialize([]byte(`{"id":42}`), nptr.Interface())
ping = nptr.Interface()
fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why?
}
Problem
See this playground: http://play.golang.org/p/dWku6SPqj5 Basically, the library I'm working on receives an `interface{}` as a parameter and then needs to `json.Unmarshal` that from a byte array. Under the covers, the `interface{}` parameter is a struct that matches the json structure of the byte array but the library doesn't have a reference to that struct (but it does have a reference to the corresponding reflect.Type through). Why can't the json package detect the underlying type? For some reason it's giving back a simple map instead of the actual struct. Here's the code: ``` package main import "fmt" import "encoding/json" import "reflect" func main() { good() bad() } func good() { var ping Ping = Ping{} deserialize([]byte(`{"id":42}`), &ping) fmt.Println("DONE:", ping.ID) } func bad() { var ping interface{} = Ping{} deserialize([]byte(`{"id":42}`), &ping) fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why? } func deserialize(stuff []byte, thing interface{}) { value := reflect.ValueOf(thing) fmt.Printf("%+v | %v\n", value, value.Kind()) err := json.Unmarshal(stuff, thing) if err != nil { panic(err) } } type Ping struct { ID int `json:"id"` } ```