I want to use a generic function to unmarshal different types:
type Foo struct {
Name string
Another string
}
type Bar struct {
Name string
Some string
}
func unmarshal(data []byte, val *[]map[string]interface{}) {
err := json.Unmarshal(data, val)
if err != nil || (*val)[0]["Name"] == "" {
*val = nil
}
}
func main() {
var foos []Foo
var bars []Bar
// fooData and barData are JSON strings retrieved from database
unmarshal(fooData, &foos)
unmarshal(barData, &bars)
}
I got an error like cannot use &foo (type *[]Foo) as type *[]map[string]interface {} in argument to unmarshal
.
I've tried use val interface{}
as the parameter but it doesn't support index.
How can I achieve the goal then? Thanks.
To work with arbitrary slice types, declare the argument as type interface{}
and use reflection to access the value:
func unmarshal(data []byte, v interface{}) {
err := json.Unmarshal(data, v)
rv := reflect.ValueOf(v).Elem()
if err != nil || rv.Len() == 0 || rv.Index(0).FieldByName("Name").Interface() == "" {
rv.Set(reflect.Zero(rv.Type()))
}
}