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

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

问题描述:

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)

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