Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reflection go(reflect):如何实例化任意类型并设置已知的嵌入字段_Reflection_Go - Fatal编程技术网

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

Reflection go(reflect):如何实例化任意类型并设置已知的嵌入字段,reflection,go,Reflection,Go,考虑以下类型声明: type ( Embedded struct{} Actual1 struct{ *Embedded } Actual2 struct{ *Embedded } Actual3 struct{ *Embedded } ) 现在考虑下面的函数,其中 i 可以是类型实际1>代码>,实际2>代码>,或实际3/代码>(或任何其他类型的嵌入代码嵌入/代码>)。我不能做类型断言或类型切换,因为我不知道有多少类型包含嵌入的,我所知道的I就是它确实嵌入了嵌入

考虑以下类型声明:

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

现在考虑下面的函数,其中<代码> i <代码>可以是类型<代码>实际1>代码>,<代码>实际2>代码>,或<代码>实际3/代码>(或任何其他类型的嵌入代码<代码>嵌入/代码>)。我不能做类型断言或类型切换,因为我不知道有多少类型包含

嵌入的
,我所知道的
I
就是它确实嵌入了
嵌入的
类型。此函数将实例化与
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

我想我要问的是这两个问题的结合:


    • 使用反射,您可以这样做:

      • 从指向该结构的指针的类型获取该结构的类型
      • 实例化并取消引用它
      • 用指针的值设置字段的值(按名称查找)
      代码:


      操场:

      完美!我错过了TypeOf(I)之后的.Elem()调用。
      v := reflect.New(reflect.TypeOf(i).Elem()).Elem()
      f := reflect.ValueOf(field)
      v.FieldByName("Embedded").Set(f)
      return v.Interface()