dougou5844 2018-04-19 15:33
浏览 70
已采纳

进行反思恐慌:使用interface {}作为类型进行呼叫

I was tinkering with reflection in Go, and I came across an interesting scenario. call1() works (returns "hello!") while call2() panics with reflect: Call using interface {} as type string.

In the code below, the only difference between call1() and call2() is how inValue is created and initialized. I can see clearly why call1() results in inValue being a string, while call2() results in inValue being an interface, so my question is not so much as to why my code produces this, but rather:

Why can't Go perform the function call in the second case? I thought the interface still contains all the necessary information for calling the method successfully, given that xCopy is still really representing a string underneath. (Yes, I did already read the laws of reflection)

I'll note that due to what I'm working on, I do need inValue to be settable within the function (hence the use of pointers).

Thanks!

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()
}

Edit

Perhaps the question then becomes: Why doesn't Go assign the real type, rather than interface, for inValue := reflect.ValueOf(&xCopy).Elem()?

  • 写回答

1条回答 默认 最新

  • dousuiguang9328 2018-04-19 15:53
    关注

    The panic message explains the problem. The value in reflect.ValueOf(&xCopy) has type *interface{}. The Elem() of this value has type interface{}. The function argument is of type string. An interface{} value is not a string value, even when the interface{} contains a string.

    Note that the address of an interface value is a pointer to the interface, not a pointer to the value in the interface.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况