【发布时间】:2021-07-24 20:49:00
【问题描述】:
尝试使用“反射”包设置接口值时遇到了麻烦。接口值实际上是在结构的结构内。在Go Playground中查看我的代码
基本上,在initProc 内部,我想将dummyAFunc 函数分配给Box 结构中的DummyA 字段
package main
import (
"fmt"
"reflect"
)
type Box struct {
Name string
DummyA interface{}
}
type SmartBox struct {
Box
}
func dummyAFunc(i int) {
fmt.Println("dummyAFunc() is here!")
}
func initProc(inout interface{}) {
// Using "inout interface{}", I can take any struct that contains Box struct
// And my goal is assign dummyAFunc to dummyA in Box struct
iType:=reflect.TypeOf(inout)
iValue:=reflect.ValueOf(inout)
fmt.Println("Type & value:", iType.Elem(), iValue.Elem()) // Type & value: *main.SmartBox &{{ <nil>}}
e := reflect.ValueOf(inout).Elem()
fmt.Println("Can set?", e.CanSet()). // true
fmt.Println("NumField", e.NumField()) // panic: reflect: call of reflect.Value.NumField on ptr Value ?????
fmt.Println("NumMethod", e.NumMethod()) // NumMethod = 0
}
func main() {
smartbox := new (SmartBox)
initProc(&smartbox)
}
我是 Go 新手,我已经阅读了 The laws of Reflection,但仍然无法弄清楚。请帮忙。谢谢!
【问题讨论】:
-
new返回一个 pointer 指向给定类型的实例,&也返回一个 pointer 指向表达式的类型它在前面。所以你实际上是在将**SmartBox传递给initProc。只对那个值执行一次Elem会给你*SmartBox,并且指针没有字段,只有它们指向的结构有字段,所以你不能在指针上调用NumField。 -
从上面的解决方案应该很明显,要么使用
Elem().Elem(),要么只将*SmartBox而不是**SmartBox传递给initProc。 -
谢谢@mkopriva。它为像我这样的围棋新手节省了一天的时间!
标签: go reflection go-reflect