Go中如何创建约束为proto.Message的泛型类型*T的实例?
解决泛型函数中实例化Proto指针类型的问题
首先明确核心需求:你要实现的泛型函数中,类型参数T是*MyProtoMessage这类实现了proto.Message的指针类型,需要创建一个非nil的T类型实例(你描述的*T应为笔误,因为T本身已是指针,*T会是指针的指针,这显然不是实际需要的)。
以下是两种可行的解决方案:
方案1:利用Protobuf官方包的proto.New函数
这是最简洁的实现方式,Protobuf官方包提供了专门的函数来创建对应类型的新实例:
import "google.golang.org/protobuf/proto" func f[T proto.Message]() T { var zero T // proto.New会根据传入的Message类型创建新实例,断言为T类型返回 return proto.New(zero).(T) }
调用方式完全符合你的预期:f[*MyProtoMessage](),返回的就是初始化完成的*MyProtoMessage实例。
方案2:通过反射实现
如果不想依赖proto.New,可以用反射直接创建底层非指针类型的实例,再取地址得到T类型:
import "reflect" func f[T proto.Message]() T { // 获取T指向的底层元素类型(T是*MyProtoMessage,Elem().Elem()得到MyProtoMessage类型) elemType := reflect.TypeOf((*T)(nil)).Elem().Elem() // 创建元素类型的指针实例,并转换为T类型返回 return reflect.New(elemType).Interface().(T) }
你之前的代码报错原因
lo.Empty[T]()返回的是T类型的零值(因为T是指针类型,零值为nil),reflect.ValueOf(nil)会生成一个零值的reflect.Value,调用Indirect后仍然是零值状态,此时调用Interface()就会触发reflect: call of reflect.Value.Interface on zero Value错误。
内容的提问来源于stack exchange,提问作者Noel Yap
相关产品推荐
相关产品推荐

