【发布时间】:2018-09-30 04:27:58
【问题描述】:
我正在修补 Go 中的反射,我遇到了一个有趣的场景。 call1() 有效(返回 "hello!"),而 call2() 与 reflect: Call using interface {} as type string 发生恐慌。
在下面的代码中,call1() 和call2() 之间的唯一区别是inValue 的创建和初始化方式。我可以清楚地看到为什么call1() 导致inValue 成为string,而call2() 导致inValue 成为interface,所以我的问题不是为什么我的代码会产生这个,而是:
为什么 Go 不能执行第二种情况的函数调用?我认为接口仍然包含成功调用该方法所需的所有信息,因为xCopy 仍然真正代表下面的字符串。 (是的,我确实已经阅读了laws of reflection)
我会注意到,由于我正在处理的工作,我确实需要在函数中设置 inValue(因此使用指针)。
谢谢!
func main() {
fmt.Println(call1(foo, "hello"))
fmt.Println(call2(foo, "hello"))
}
func foo(x string) string {
return x + "!"
}
func call1(f, x interface{}) interface{} {
fValue := reflect.ValueOf(f)
inValue := reflect.New(reflect.TypeOf(x)).Elem()
inValue.Set(reflect.ValueOf(x))
inValue.Set(fValue.Call([]reflect.Value{inValue})[0])
return inValue.Interface()
}
func call2(f, x interface{}) interface{} {
fValue := reflect.ValueOf(f)
xCopy := x
inValue := reflect.ValueOf(&xCopy).Elem()
inValue.Set(fValue.Call([]reflect.Value{inValue})[0])
return inValue.Interface()
}
编辑
也许问题就变成了:为什么 Go 不为 inValue := reflect.ValueOf(&xCopy).Elem() 分配真正的类型,而不是 interface?
【问题讨论】:
标签: go reflection interface call panic