【问题标题】:Set a struct field with field type of a interface使用接口的字段类型设置结构字段
【发布时间】:2015-02-18 19:53:23
【问题描述】:

有没有办法使用反射设置接口字段?当我尝试设置它时,它惊慌地说该值不可寻址。

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)

【问题讨论】:

  • 你会反思什么?上面的代码编译得很好。你有什么问题?
  • 为此,通常使用type assertion。你想用反射做什么?

标签: reflection go


【解决方案1】:

接口没有字段,它们只定义了它们包含的值的方法集。反射接口时,可以用Value.Elem()提取值。

您也不能Set 未导出的字段。您需要将 B 类型中的字段名称大写。遍历字段时,使用Value.CanSet() 测试它们是否可设置。 CanSet() 也将返回 false,如果该值不可寻址,或者该值仍在接口中。

您的代码的工作示例: http://play.golang.org/p/Mf1HENRSny

【讨论】:

  • 所以没有办法设置一个以interface为类型的字段?
  • 当然可以。只要它是一个有效的赋值,字段的类型是什么并不重要。您最初的问题没有意义,并且可能是您困惑的根源,因为没有“接口字段”之类的东西。接口只定义一个方法集。您需要接口中包含的值,可以通过Elem()(或reflect.Indirect())获取。
猜你喜欢
  • 2019-02-06
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 2017-12-28
  • 1970-01-01
  • 2018-12-25
  • 2011-11-28
  • 1970-01-01
相关资源
最近更新 更多