golang protobuf 无法在通用类型中解组。

huangapple go评论111阅读模式
英文:

golang protobuf can not unmarshal in a generic type

问题

proto.Unmarshal([]byte{}, req)
英文:
type Msg[T any] interface {
	*T
	proto.Message
}

func Handle[T any, U Msg[T]](cb func(req U) (proto.Message, error)) {
	msg := new(T)
	if err := proto.Unmarshal([]byte{}, msg); err != nil {
	}
	_, _ = cb(msg)
}

func main() {
	Handle(donSomething)
}

func doSomething(req *pb.Hello) (proto.Message, error) {
	_ = proto.Unmarshal([]byte{}, req)
	return nil, nil
}

why proto.Unmarshal Cannot use 'msg' (type *T) as the type Message in Handle generic funcion.

how can i use new(T) in a generic funcion with protobuf

答案1

得分: 2

在你的程序中,T 受到 any 的限制,因此指针类型 *T 不再与 protobuffer 类型相关。它只是一个指向未指定类型的指针。

而应该使用:

msg := U(new(T))

这样,你就会得到一个非空指针,指向推断出的 T 的类型 — 在这里它将是 pb.Hellonew(T) 创建一个指向 pb.Hello 零值的指针,而转换 U() 告诉编译器 *T 真正满足 proto.Message 接口。

英文:

In your program T is constrained by any, so the pointer type *T bears no relation to the protobuffer type anymore. It's just a pointer to an unspecified type.

Instead use:

msg := U(new(T))

This way you have a non-nil pointer to whatever T is inferred to — here it will be pb.Hello, new(T) creates a pointer to a pb.Hello zero value, and the conversion U() tells the compiler that *T really satisfies the proto.Message interface.

huangapple
  • 本文由 发表于 2023年8月9日 13:14:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76864765-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定