[英]How to use "reflect" to set interface value inside a struct of struct
Had a rough time trying to set the interface value by using "reflect" package.尝试使用“反射”package 设置接口值时遇到了麻烦。 The interface value is actually inside a struct of a struct.接口值实际上是在结构的结构内。 See my code in Go Playground在Go Playground中查看我的代码
Basically, inside initProc
, I want to assign dummyAFunc
function to DummyA
field in Box
struct基本上,在initProc
中,我想将dummyAFunc
function 分配给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)
}
I'm new to Go and I've read the The laws of Reflection but still can't figure it out.我是 Go 的新手,我已经阅读了反射定律,但仍然无法弄清楚。 Please help.请帮忙。 Thanks!谢谢!
You are passing a **SmartBix
to initProc
.您将**SmartBix
传递给initProc
。 So when you dereference once with reflect's Elem()
you are still getting a pointer ( *Smart box
).因此,当您使用反射的Elem()
取消引用一次时,您仍然会得到一个指针( *Smart box
)。
Since new
already returns a pointer, just use:由于new
已经返回一个指针,只需使用:
smartbox := new (SmartBox)
// InitProc(smartbox) // **SmartBox
InitProc(smartbox) // *SmartBox
https://play.golang.org/p/j4q6aq6QL_4 https://play.golang.org/p/j4q6aq6QL_4
EDIT编辑
To update the input struct's DummyA
field, you can do something like this:要更新输入结构的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
}
Working example: https://play.golang.org/p/VE751GtSGEw工作示例: https://play.golang.org/p/VE751GtSGEw
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.