考虑以下类型声明:
type (
Embedded struct{}
Actual1 struct{ *Embedded }
Actual2 struct{ *Embedded }
Actual3 struct{ *Embedded }
)
现在考虑以下函数,其中i
可以是Actual1
,Actual2
或Actual3
类型(或嵌入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
的调用。
我认为我要求的是这两个问题的组合:
答案 0 :(得分:2)
使用反射,你可以这样做:
代码:
v := reflect.New(reflect.TypeOf(i).Elem()).Elem()
f := reflect.ValueOf(field)
v.FieldByName("Embedded").Set(f)
return v.Interface()