Go 如何使用;反映;在struct的struct内设置接口值

Go 如何使用;反映;在struct的struct内设置接口值,go,reflection,go-reflect,Go,Reflection,Go Reflect,尝试使用“reflect”包设置接口值时遇到了困难。接口值实际上位于结构的结构中。在中查看我的代码 基本上,在initProc中,我想将dummyAFunc函数分配给Boxstruct中的DummyA字段 主程序包 进口( “fmt” “反映” ) 类型框结构{ 名称字符串 DummyA接口{} } 类型SmartBox结构{ 盒子 } func dummyAFunc(i int){ Println(“dummyAFunc()在这里!”) } func initProc(inout接口{}){

尝试使用“reflect”包设置接口值时遇到了困难。接口值实际上位于结构的结构中。在中查看我的代码

基本上,在
initProc
中,我想将
dummyAFunc
函数分配给
Box
struct中的
DummyA
字段

主程序包
进口(
“fmt”
“反映”
)
类型框结构{
名称字符串
DummyA接口{}
}
类型SmartBox结构{
盒子
}
func dummyAFunc(i int){
Println(“dummyAFunc()在这里!”)
}
func initProc(inout接口{}){
//使用“inout接口{}”,我可以获取任何包含Box结构的结构
//我的目标是将dummyAFunc分配给Box结构中的dummyA
iType:=reflect.TypeOf(inout)
iValue:=reflect.ValueOf(inout)
fmt.Println(“类型和值:”,iType.Elem(),iValue.Elem())//类型和值:*main.SmartBox&{}
e:=reflect.ValueOf(inout.Elem())
fmt.Println(“可以设置吗?”,e.CanSet())。//true
fmt.Println(“NumField”,e.NumField())//panic:reflect:对ptr值调用reflect.Value.NumField?????
fmt.Println(“NumMethod”,e.NumMethod())//NumMethod=0
}
func main(){
智能盒:=新的(智能盒)
initProc(&smartbox)
}

我是新来的,我读过这本书,但还是搞不懂。请帮忙。谢谢

您正在将一个
**SmartBix
传递给
initProc
。因此,当您使用reflect的
Elem()
取消引用一次时,仍然会得到一个指针(
*智能盒

由于
new
已返回指针,只需使用:

smartbox := new (SmartBox)

// InitProc(smartbox) // **SmartBox
InitProc(smartbox) // *SmartBox


编辑

要更新输入结构的
DummyA
字段,可以执行以下操作:

func initProc2(v interface{}) error {

    if reflect.TypeOf(v).Kind() != reflect.Ptr {
        return fmt.Errorf("value must be a pointer")
    }

    dv := reflect.ValueOf(v).Elem()

    if dv.Kind() != reflect.Struct {
        return fmt.Errorf("value must be a pointer to a struct/interface")
    }

    const fname = "DummyA" // lookup field name

    f := dv.FieldByName(fname)

    if !f.CanSet() {
        return fmt.Errorf("value has no field %q or cannot be set", fname)
    }

    nv := reflect.ValueOf(dummyAFunc)

    f.Set(nv)

    return nil
}

工作示例:

new
返回指向给定类型实例的指针,
&
还返回指向其前面表达式类型的指针。因此,实际上您正在将
**SmartBox
传递到
initProc
。只对该值执行一次
Elem
,将得到
*SmartBox
,指针没有字段,只有指向的结构有字段,因此不能对指针调用
NumField
。从上面看,解决方案应该很明显,可以使用
Elem().Elem()
或仅将
*SmartBox
而不是
**SmartBox
传递到
initProc
。谢谢@mkopriva。这为像我这样的新手节省了一天的时间!谢谢@colm.anseo。我对它进行了修改,使它能够访问
框中的字段
,但是如何将
框的DummyA
字段值设置为
dummyAFunc
?@calvinchso我用字段更新代码更新了答案。太棒了!谢谢你的例子。