You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:02:39