使用接口类型设置结构字段

huangapple go评论93阅读模式
英文:

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(&quot;field&quot;),
  should: CreateA(&quot;should&quot;),
  mirror: CreateA(&quot;mirror&quot;),
}

func MirrorField(b *B) {
   t := reflect.TypeOf(b)
   v := reflect.ValueOf(b)
   for i := 0; i &lt; 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 = &amp;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

huangapple
  • 本文由 发表于 2015年2月19日 03:53:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/28592661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定