[英]go reflection: get correct struct type of interface
考虑一下:
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
接口转换为正确的类型? 换句话说,我可以通过传递字符串(或使用一些反射方法)而不是将程序可用的类型作为符号来键入类型断言吗?
是的,这是可能的。 这是您的代码更新:
func DoThing(fn interface{}) {
// Get first arg of the function
firstArg := reflect.TypeOf(fn).In(0)
// Get the PtrTo to the first function parameter
structPtr := reflect.New(firstArg)
// Convert to Interface
// Note that I can't assert this to .(myStruct) type
instance := structPtr.Interface()
// Unmarshal the JSON
json.Unmarshal(jsonData, instance)
// Call the function
vfn := reflect.ValueOf(fn)
vfn.Call([]reflect.Value{structPtr.Elem()})
}
做出的改变:
structPtr
(一个指针)传递给json.Unmarshal
; 传递一个值,您将看不到更改 json.Unmarshal
时删除获取instance
的地址; 通常没有一个很好的理由有一个指向接口的指针 fn
时使用structPtr
而不是instance
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.