I want to write a function that receives several types of structs and unmarshals them from JSON. To this end, I have another set of functions with a pre-defined signature that return the struct instances but since each function returns a different type of struct the function signature has interface{}
as the return type.
When I send json.Unmarshal a concrete struct it works as I expected but when I send the same struct as interface{}
it converts it to a map.
Here is a simplified example code that depicts the problem:
package main
import (
"encoding/json"
"fmt"
)
type Foo struct {
Bar string `json:"bar"`
}
func getFoo() interface{} {
return Foo{"bar"}
}
func main() {
fooInterface := getFoo()
fooStruct := Foo{"bar"}
fmt.Println(fooInterface) //{bar}
fmt.Println(fooStruct) //{bar}
myJSON := `{"bar":"This is the new value of bar"}`
jsonBytes := []byte(myJSON)
err := json.Unmarshal(jsonBytes, &fooInterface )
if err != nil {
fmt.Println(err)
}
fmt.Println(fooInterface) //map[bar:This is the new value of bar]
err = json.Unmarshal(jsonBytes, &fooStruct)
if err != nil {
fmt.Println(err)
}
fmt.Println(fooStruct) //{This is the new value of bar}
}
https://play.golang.org/p/tOO7Ki_i4c
I expected json.Unmarshal to use the concrete struct behind the interface for unmarshaling but it doesn't and just assigns the map of values to the passed interface.
Why doesn't it use the concrete struct and is there a way to tell it to use the concrete struct type without explicit casting (I don't know the explicit type at design time)?