go(reflect):如何实例化任意类型并设置已知的嵌入字段

时间:2015-08-21 16:13:24

标签: reflection go

考虑以下类型声明:

type (
    Embedded struct{}
    Actual1 struct{ *Embedded }
    Actual2 struct{ *Embedded }
    Actual3 struct{ *Embedded }
)

现在考虑以下函数,其中i可以是Actual1Actual2Actual3类型(或嵌入Embedded的任何其他类型喜欢的方式)。我无法进行类型断言或类型切换,因为我不知道有多少类型包含Embedded,我所知道的i是它确实嵌入了Embedded类型。此函数将实例化与i相同类型的新实例,并在新实例化的副本实例上设置embed

func New(i interface{}, field *Embedded) interface{} {
    // Step 1. instantiate new instance of `i`, of same underlying type as `i`
    // Step 2. set `i.Embedded` to `field`
    // Step 3. return the new instance.
}

以下是用法的用法:

func main() {
    actual := &Actual1{}
    embed := &Embedded{}
    copied := New(actual, embed)
    if copied.(Actual1).Embedded != embed {
        log.Fatal("It didn't work!")
    }
}

New(...)函数的正确实现不能使用类型断言或类型切换,也不会导致对上面显示的log.Fatal的调用。

我认为我要求的是这两个问题的组合:

1 个答案:

答案 0 :(得分:2)

使用反射,你可以这样做:

  • 从指向它的指针类型中获取结构的类型
  • 实例化并解析它
  • 使用指针值
  • 设置字段的值(按名称查找)

代码:

v := reflect.New(reflect.TypeOf(i).Elem()).Elem()
f := reflect.ValueOf(field)
v.FieldByName("Embedded").Set(f)
return v.Interface()

游乐场:http://play.golang.org/p/fX413svXDv

相关问题