Go Reflection Panic:使用 interface{} 作为类型调用
Go Reflection Panic: Call using interface{} as type
我在 Go 中修改反射,遇到了一个有趣的场景。 call1()
有效(returns "hello!"
),而 call2()
因 reflect: Call using interface {} as type string
而出现恐慌。
在下面的代码中,call1()
和 call2()
之间的唯一区别是如何创建和初始化 inValue
。我可以看清楚为什么call1()
导致inValue
成为string
,而call2()
导致inValue
成为一个interface
,所以我的问题不是我的代码为什么会产生这个,而是:
为什么Go在第二种情况下无法执行函数调用?我认为接口仍然包含成功调用方法的所有必要信息,因为 xCopy
仍然真正代表下面的字符串。 (是的,我确实已经阅读了 laws of reflection)
我会注意到,由于我正在做的事情,我 do 需要 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
?
紧急消息说明了问题。 reflect.ValueOf(&xCopy)
中的值具有类型 *interface{}
。此值的 Elem()
具有类型 interface{}
。函数参数的类型为 string
。 interface{}
值不是 string
值,即使 interface{}
包含 string
.
注意接口值的地址是指向接口的指针,而不是指向接口中值的指针。
我在 Go 中修改反射,遇到了一个有趣的场景。 call1()
有效(returns "hello!"
),而 call2()
因 reflect: Call using interface {} as type string
而出现恐慌。
在下面的代码中,call1()
和 call2()
之间的唯一区别是如何创建和初始化 inValue
。我可以看清楚为什么call1()
导致inValue
成为string
,而call2()
导致inValue
成为一个interface
,所以我的问题不是我的代码为什么会产生这个,而是:
为什么Go在第二种情况下无法执行函数调用?我认为接口仍然包含成功调用方法的所有必要信息,因为 xCopy
仍然真正代表下面的字符串。 (是的,我确实已经阅读了 laws of reflection)
我会注意到,由于我正在做的事情,我 do 需要 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
?
紧急消息说明了问题。 reflect.ValueOf(&xCopy)
中的值具有类型 *interface{}
。此值的 Elem()
具有类型 interface{}
。函数参数的类型为 string
。 interface{}
值不是 string
值,即使 interface{}
包含 string
.
注意接口值的地址是指向接口的指针,而不是指向接口中值的指针。