如何获取任意原始消息作为输入并调用protojson.Marshal进行封包

问题描述

我正在编写一个函数,该函数接受任意原始消息并对其进行处理

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()
}

这实质上可以防止在需要指针的情况下无意间传递值的副本。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...