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()