golang protobuf can not unmarshal in a generic type

295 views Asked by At
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

There are 1 answers

1
blackgreen On

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.