英文:
Set a struct field with field type of a interface
问题
使用反射(reflect)设置接口字段有没有办法?当我尝试设置时,它会抛出一个错误,说值是不可寻址的。
type A interface{...}
func CreateA(name string) A {...}
type B struct {
field A
should A
mirror A
}
// 初始化的常规方式
var b = B{
field: CreateA("field"),
should: CreateA("should"),
mirror: CreateA("mirror"),
}
func MirrorField(b *B) {
t := reflect.TypeOf(b)
v := reflect.ValueOf(b)
for i := 0; i < t.NumField(); i++ {
setTo := CreateA(t.Field(i).Name)
fieldVal := v.Elem().Field(i)
fieldVal.Set(reflect.ValueOf(setTo))
}
}
// 我想要的是像这样
var b = &B{}
MirrorField(b)
以上是你提供的代码的翻译。
英文:
Is there any way to set an interface field using reflect? When i tried to set it, it paniced saying that the value is non addressable.
type A interface{...}
func CreateA(name string) A {...}
type B struct {
field A
should A
mirror A
}
// normal way of initializing
var b = B{
field: CreateA("field"),
should: CreateA("should"),
mirror: CreateA("mirror"),
}
func MirrorField(b *B) {
t := reflect.TypeOf(b)
v := reflect.ValueOf(b)
for i := 0; i < t.NumField(); i++ {
setTo = CreateA(t.Field(1).Name)
fieldVal := v.Field(i)
fieldVal.Set(reflect.ValueOf(setTo))
}
}
// what i want is something like
var b = &B{}
MirrorField(b)
答案1
得分: 2
接口没有字段,它们只定义了包含的值的方法集合。在反射接口时,可以使用Value.Elem()
提取值。
您也不能设置未公开的字段。您需要将B
类型中的字段名称大写。在遍历字段时,使用Value.CanSet()
来测试它们是否可设置。如果值不可寻址或值仍在接口中,CanSet()
也会返回false。
您的代码的一个可工作的示例:
http://play.golang.org/p/Mf1HENRSny
英文:
Interfaces don't have fields, they only define a method set of the value they contain. When reflecting on an interface, you can extract the value with Value.Elem()
.
You also can't Set
unexported fields. You need to capitalize the field names in your B
type. When iterating over the fields, use Value.CanSet()
to test if they are settable. CanSet()
will also return false is the value isn't addressable, or the value is still in an interface.
A working example of your code:
http://play.golang.org/p/Mf1HENRSny
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论