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{}。函数参数的类型为 stringinterface{} 值不是 string 值,即使 interface{} 包含 string.

注意接口值的地址是指向接口的指针,而不是指向接口中值的指针。