考虑以下内容:
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)
})
}
我刚接触 Go 语言,所以担心这段代码可能不符合惯用写法。我想实现 somelibrary.DoThing
函数,使其能够通过反射正确地从函数参数中推断出结构体类型(如果可能的话)。以下是我的代码:
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)})
}
在不预先知道结构类型的情况下,json.Unmarshal只会假设instance
是map[string]interface{}
,因此在调用vfn.Call(...)
时会出现错误:
panic: reflect: Call using map[string]interface {} as type main.myStruct
是否可以将instance
接口转换为正确的类型?换句话说,我是否可以通过传递字符串(或使用某些反射方法)来进行类型断言,而不是将类型作为符号提供给程序?
DoThing
仅仅是将数据解组成结构体,所以可以写得非常简单,如下所示:json.Unmarshal(somelibrary.JsonData, myStructPtr)
- Yerken