Consider this:
type myStruct struct {
Foo string `json:"foo"`
}
func main() {
somelibrary.DoThing(func(thing myStruct) {
// myStruct should contain unmarshaled JSON
// provided by somelibrary
fmt.Printf("%v\n", thing)
})
}
I'm new to Go, so I fear this might not be idiomatic code. I'd like to implement somelibrary.DoThing
so it correctly infers the struct type from the function argument via reflection, if it's possible. Here's what I have:
const jsonData := []byte{`{"foo": "bar"}`}
func DoThing(fn interface{}) {
// Get first arg of the function
firstArg := reflect.TypeOf(fn).In(0)
structPtr := reflect.New(firstArg)
// Convert to Interface
// Note that I can't assert this to .(myStruct) type
instance := structPtr.Elem().Interface()
// Unmarshal the JSON
json.Unmarshal(jsonData, &instance)
// Call the function
vfn := reflect.ValueOf(fn)
vfn.Call([]reflect.Value{reflect.ValueOf(instance)})
}
Without knowing the struct type beforehand, json.Unmarshal just assumes that instance
is map[string]interface{}
, so I get a panic when calling vfn.Call(...)
:
panic: reflect: Call using map[string]interface {} as type main.myStruct
Is it possible to convert the instance
interface into the correct type? In other words, can I do type type assertion by passing a string (or using some reflection method) instead of having the type available to the program as a symbol?
Aucun commentaire:
Enregistrer un commentaire