问题描述
func protoToSomething(in proto.Message) ([]byte,error) {
jsonBytes,protoJsonError := protojson.Marshal(in)
if protoJsonError != nil {
return nil,protoJsonError
}
stuff here...
}
但是当我这样称呼它时:
model := myprotolib.MyRequest{
UserId: "3214",UserName: "JohnDoe",SomeValue: true,}
data,_ := protoToSomething(model)
我得到这个“ myprotolib.MyRequest没有实现protoreflect.ProtoMessage(ProtoReflect方法具有指针接收器)”
定义的func (x *MyRequest) ProtoReflect() protoreflect.Message {
(接收方使用指针的地方。)
但是当我查看protoreflect / proto.go中的定义时,我会看到
type ProtoMessage interface{ ProtoReflect() Message }
所以我很困惑,对Go还是陌生的(尽管我已经专业地使用过Protos,Java和C ++)-我如何编写一个函数,该函数接受任意的proto消息并对它做一些事情,包括protojson马歇尔?
解决方法
model
未实现该接口,因为model
为指针接收器声明了该方法。
如果使用指针接收器声明了一个方法,则只有该类型的指针实现该接口,而不是值类型。那是:
type I interface {
f()
}
type S struct {
}
func (s S) f() {}
type T struct {
}
func (t *T) f() {}
func W(intf I) {}
func main() {
s:=S{}
W(s) // This works. S has method f()
W(&s) // This works. *S has method f()
t:=T{}
W(t) // This does not work. T does not have f()
w(&t) // This works. *T has f()
}
这实质上可以防止在需要指针的情况下无意间传递值的副本。