Go 1.19中如何从nil指针动态生成其底层值?
在Go 1.19中基于泛型约束动态创建nil字段的底层值
先给出问题中的代码定义:
type A struct{} type B struct{} type Field interface { *A | *B } type Person[T Field] struct { field T }
问题核心:在do方法中,当p.field为nil时,能否根据泛型参数T的类型动态生成对应的*A或*B实例?
答案是可以实现,但需注意两个关键细节:方法接收者必须用指针(否则赋值仅作用于副本),可通过类型分支或反射两种方式创建实例。
方式一:类型分支(无反射,性能更优)
无需引入反射包,直接通过类型断言判断泛型参数的具体类型,创建对应实例:
func (p *Person[T]) do() { if p.field == nil { var t T switch any(t).(type) { case *A: p.field = new(A).(T) case *B: p.field = new(B).(T) } } }
方式二:反射(更灵活,适配多约束类型场景)
如果后续Field接口的约束类型增多,类型分支会变得繁琐,这时可以用反射包动态创建实例:
import "reflect" func (p *Person[T]) do() { if p.field == nil { // 获取泛型T指向的底层类型(A或B) elemType := reflect.TypeOf(new(T)).Elem().Elem() // 创建底层类型实例并取地址,转换为T类型赋值 p.field = reflect.New(elemType).Interface().(T) } }
必注意:使用指针接收者
原代码中do方法用值接收者Person[T]时,方法内操作的是原结构体的副本,赋值后原实例的field字段不会被更新。因此必须改为指针接收者*Person[T],才能真正修改原结构体的字段。
内容的提问来源于stack exchange,提问作者BeetleJuice
相关产品推荐
相关产品推荐

