从不同的包导入 proto 文件导致“缺少方法 protoreflect”

问题描述

我是 Go 和 Protobufs 的新手,因此这可能是一个非常菜鸟的问题。对不起。

我的 go 项目中有几个包,我想创建一个单独的包,其中包含我所有的 .proto(还有 .pb.go)文件,然后我可以在任何其他包中导入这些 proto 文件以更好地管理我所有的proto 文件

但是当我将我的 proto 文件移动到一个名为“prototemps”的单独包中并在另一个名为“reader”的包中导入“prototemps”时。在 reader.go 中,我这样做:

    sensorData := &prototemps.Sensor{}
    err := proto.Unmarshal(msg.Payload(),sensorData) 

它产生这个错误

var sensorData *prototemps.Sensor
cannot use sensorData (variable of type *prototemps.Sensor) as protoreflect.ProtoMessage value in argument to proto.Unmarshal: missing method ProtoReflect

我的项目结构如下所示:

ProjectFolder/
 /prototemps/<all .proto and .pb.go exist here>  (Package "prototemps")
 /reader/reader.go which fails when tries to do proto.Unmarshall (Package "reader")

这是我的 .proto 的样子

Syntax="proto3";
package prototemps;

import "google/protobuf/timestamp.proto";

message sensor {
      string Name = 1;
      int32 ID = 2;
      string Type = 3;
      orientation Ori = 4;
      IO IO = 5;
      google.protobuf.Timestamp ts = 6;
}

message orientation {
      int32 X = 1;
      int32 Y = 2;
      int32 Z = 3;
}

message IO {
      int32 Reads = 1;
      int32 Writes = 2;
}

这是我使用 *protoc --go_out= 生成的 .pb.go。 .proto

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: sensorData.proto

package prototemps

import (
    fmt "fmt"
    proto "github.com/golang/protobuf/proto"
    timestamppb "google.golang.org/protobuf/types/kNown/timestamppb"
    math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsversion3 // please upgrade the proto package

type Sensor struct {
    Name                 string                 `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
    ID                   int32                  `protobuf:"varint,2,name=ID,proto3" json:"ID,omitempty"`
    Type                 string                 `protobuf:"bytes,3,name=Type,proto3" json:"Type,omitempty"`
    Ori                  *Orientation           `protobuf:"bytes,4,name=Ori,proto3" json:"Ori,omitempty"`
    IO                   *IO                    `protobuf:"bytes,5,name=IO,proto3" json:"IO,omitempty"`
    Ts                   *timestamppb.Timestamp `protobuf:"bytes,6,name=ts,proto3" json:"ts,omitempty"`
    XXX_NoUnkeyedLiteral struct{}               `json:"-"`
    XXX_unrecognized     []byte                 `json:"-"`
    XXX_sizecache        int32                  `json:"-"`
}

func (m *Sensor) Reset()         { *m = Sensor{} }
func (m *Sensor) String() string { return proto.CompactTextString(m) }
func (*Sensor) ProtoMessage()    {}
func (*Sensor) Descriptor() ([]byte,[]int) {
    return fileDescriptor_a3adf506f94bdd26,[]int{0}
}

func (m *Sensor) XXX_Unmarshal(b []byte) error {
    return xxx_messageInfo_Sensor.Unmarshal(m,b)
}
func (m *Sensor) XXX_Marshal(b []byte,deterministic bool) ([]byte,error) {
    return xxx_messageInfo_Sensor.Marshal(b,m,deterministic)
}
func (m *Sensor) XXX_Merge(src proto.Message) {
    xxx_messageInfo_Sensor.Merge(m,src)
}
func (m *Sensor) XXX_Size() int {
    return xxx_messageInfo_Sensor.Size(m)
}
func (m *Sensor) XXX_discardUnkNown() {
    xxx_messageInfo_Sensor.discardUnkNown(m)
}

var xxx_messageInfo_Sensor proto.InternalMessageInfo

func (m *Sensor) GetName() string {
    if m != nil {
        return m.Name
    }
    return ""
}

func (m *Sensor) GetID() int32 {
    if m != nil {
        return m.ID
    }
    return 0
}

func (m *Sensor) GetType() string {
    if m != nil {
        return m.Type
    }
    return ""
}

func (m *Sensor) Getori() *Orientation {
    if m != nil {
        return m.Ori
    }
    return nil
}

func (m *Sensor) GetIO() *IO {
    if m != nil {
        return m.IO
    }
    return nil
}

func (m *Sensor) GetTs() *timestamppb.Timestamp {
    if m != nil {
        return m.Ts
    }
    return nil
}

type Orientation struct {
    X                    int32    `protobuf:"varint,name=X,proto3" json:"X,omitempty"`
    Y                    int32    `protobuf:"varint,name=Y,proto3" json:"Y,omitempty"`
    Z                    int32    `protobuf:"varint,name=Z,proto3" json:"Z,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func (m *Orientation) Reset()         { *m = Orientation{} }
func (m *Orientation) String() string { return proto.CompactTextString(m) }
func (*Orientation) ProtoMessage()    {}
func (*Orientation) Descriptor() ([]byte,[]int{1}
}

func (m *Orientation) XXX_Unmarshal(b []byte) error {
    return xxx_messageInfo_Orientation.Unmarshal(m,b)
}
func (m *Orientation) XXX_Marshal(b []byte,error) {
    return xxx_messageInfo_Orientation.Marshal(b,deterministic)
}
func (m *Orientation) XXX_Merge(src proto.Message) {
    xxx_messageInfo_Orientation.Merge(m,src)
}
func (m *Orientation) XXX_Size() int {
    return xxx_messageInfo_Orientation.Size(m)
}
func (m *Orientation) XXX_discardUnkNown() {
    xxx_messageInfo_Orientation.discardUnkNown(m)
}

var xxx_messageInfo_Orientation proto.InternalMessageInfo

func (m *Orientation) GetX() int32 {
    if m != nil {
        return m.X
    }
    return 0
}

func (m *Orientation) GetY() int32 {
    if m != nil {
        return m.Y
    }
    return 0
}

func (m *Orientation) GetZ() int32 {
    if m != nil {
        return m.Z
    }
    return 0
}

type IO struct {
    Reads                int32    `protobuf:"varint,name=Reads,proto3" json:"Reads,omitempty"`
    Writes               int32    `protobuf:"varint,name=Writes,proto3" json:"Writes,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func (m *IO) Reset()         { *m = IO{} }
func (m *IO) String() string { return proto.CompactTextString(m) }
func (*IO) ProtoMessage()    {}
func (*IO) Descriptor() ([]byte,[]int{2}
}

func (m *IO) XXX_Unmarshal(b []byte) error {
    return xxx_messageInfo_IO.Unmarshal(m,b)
}
func (m *IO) XXX_Marshal(b []byte,error) {
    return xxx_messageInfo_IO.Marshal(b,deterministic)
}
func (m *IO) XXX_Merge(src proto.Message) {
    xxx_messageInfo_IO.Merge(m,src)
}
func (m *IO) XXX_Size() int {
    return xxx_messageInfo_IO.Size(m)
}
func (m *IO) XXX_discardUnkNown() {
    xxx_messageInfo_IO.discardUnkNown(m)
}

var xxx_messageInfo_IO proto.InternalMessageInfo

func (m *IO) GetReads() int32 {
    if m != nil {
        return m.Reads
    }
    return 0
}

func (m *IO) GetWrites() int32 {
    if m != nil {
        return m.Writes
    }
    return 0
}

func init() {
    proto.RegisterType((*Sensor)(nil),"prototemps.sensor")
    proto.RegisterType((*Orientation)(nil),"prototemps.orientation")
    proto.RegisterType((*IO)(nil),"prototemps.IO")
}

func init() {
    proto.RegisterFile("sensorData.proto",fileDescriptor_a3adf506f94bdd26)
}

var fileDescriptor_a3adf506f94bdd26 = []byte{
    // 259 bytes of a gzipped FileDescriptorProto
    0x1f,0x8b,0x08,0x00,0x09,0x6e,0x88,0x02,0xff,0x4c,0x8e,0xcf,0x4a,0xc3,0x40,0x10,0xc6,0xd9,0xb4,0x38,0x95,0x22,0x83,0xe8,0xd2,0x4e,0xea,0x61,0x0b,0xf5,0xe0,0xf4,0x81,0xa5,0x60,0xdb,0x16,0xd7,0xb2,0x77,0x3c,0xf8,0x64,0xbe,0x9e,0xfb,0x27,0xc5,0x9c,0x32,0xdf,0xe4,0x37,0xfe,0xca,0xeb,0xce,0x5b,0xb7,0x56,0xa4,0x44,0xef,0x2c,0x59,0x84,0x21,0xdd,0xf6,0x7e,0x71,0x7f,0x97,0x69,0x75,0xfc,0x5c,0x92,0xb5,0xd5,0x19,0xae,0x54,0xb9,0x01,0x11,0xa6,0x6f,0xaa,0x3d,0xb0,0xc7,0x99,0x66,0x43,0xb1,0xf3,0x6c,0xc8,0x7a,0xcd,0x89,0x33,0x3e,0xc1,0x86,0x4f,0x6a,0xb6,0xba,0x15,0xaf,0x8c,0xee,0x48,0x91,0x9d,0x0c,0xde,0x85,0x8f,0xc9,0x4d,0x13,0x1b,0x7c,0x82,0xe2,0xec,0x2e,0x67,0xa8,0xfa,0xa3,0xbc,0x04,0x4b,0xbb,0x98,0x36,0x74,0x1d,0x55,0x94,0xc0,0x6b,0x28,0x1f,0xb8,0xa0,0x87,0xac,0xc4,0xcb,0x5f,}

任何帮助将不胜感激,谢谢!

解决方法

如果您对 protoc-gen-go 版本感到满意,您可能只想更改调用 goproto.Unmarshal 导入。我知道有两个选项:

  • "github.com/golang/protobuf/proto"

  • "google.golang.org/protobuf/proto"

试试你没有的。希望对其他人也有帮助!

,

错误消息指出变量 sensorData 缺少方法 ProtoReflect。检查生成的文件,这是正确的。 Sensor 类型没有这样的方法。

在我看来,您在使用不同版本的 Go protobuf 时遇到了问题。确保您使用与用于编组/解组的相同版本来生成 *.pb.go 文件。

现在 Go 世界中有不同的包不兼容,因为 API 发生了重大变化:https://blog.golang.org/protobuf-apiv2

如果您从 protobuf 开始,我肯定会尝试使用新软件包。确保您遵循的任何介绍都使用您正在使用的包。

,

检查您的 $GOPATH/bin 并查看是否有名为 proto-gen-go-grpc 的二进制文件

如果是这样,请尝试运行以下命令

protoc --go_out=. --go-grpc_out=. .proto

--go_out只在go lang中生成protobuf,不会生成gGRPC方法

相关问答

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