go - ProtoBuf 教程:“AddressBook 没有实现“github.com/gogo/protobuf/proto”.Message(ProtoMessage 方法有指针接收器)”
问题描述
我正在尝试遵循有关 ProtoBufs 的本教程:https ://developers.google.com/protocol-buffers/docs/gotutorial 。我有以下项目结构:
.
├── addressbook
│ ├── addressbook.pb.go
│ └── addressbook.proto
├── go.mod
├── go.sum
└── main.go
addressbook.proto
在哪里
syntax = "proto3";
package addressbook;
import "google/protobuf/timestamp.proto";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
google.protobuf.Timestamp last_updated = 5;
}
message AddressBook {
repeated Person people = 1;
}
和自动生成的(带protoc addressbook.proto --go-out=.
)addressbook.pb.go
读取
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: addressbook.proto
package addressbook
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
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 Person_PhoneType int32
const (
Person_MOBILE Person_PhoneType = 0
Person_HOME Person_PhoneType = 1
Person_WORK Person_PhoneType = 2
)
var Person_PhoneType_name = map[int32]string{
0: "MOBILE",
1: "HOME",
2: "WORK",
}
var Person_PhoneType_value = map[string]int32{
"MOBILE": 0,
"HOME": 1,
"WORK": 2,
}
func (x Person_PhoneType) String() string {
return proto.EnumName(Person_PhoneType_name, int32(x))
}
func (Person_PhoneType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_1eb1a68c9dd6d429, []int{0, 0}
}
type Person struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"`
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
Phones []*Person_PhoneNumber `protobuf:"bytes,4,rep,name=phones,proto3" json:"phones,omitempty"`
LastUpdated *timestamp.Timestamp `protobuf:"bytes,5,opt,name=last_updated,json=lastUpdated,proto3" json:"last_updated,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Person) Reset() { *m = Person{} }
func (m *Person) String() string { return proto.CompactTextString(m) }
func (*Person) ProtoMessage() {}
func (*Person) Descriptor() ([]byte, []int) {
return fileDescriptor_1eb1a68c9dd6d429, []int{0}
}
func (m *Person) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Person.Unmarshal(m, b)
}
func (m *Person) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Person.Marshal(b, m, deterministic)
}
func (m *Person) XXX_Merge(src proto.Message) {
xxx_messageInfo_Person.Merge(m, src)
}
func (m *Person) XXX_Size() int {
return xxx_messageInfo_Person.Size(m)
}
func (m *Person) XXX_DiscardUnknown() {
xxx_messageInfo_Person.DiscardUnknown(m)
}
var xxx_messageInfo_Person proto.InternalMessageInfo
func (m *Person) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Person) GetId() int32 {
if m != nil {
return m.Id
}
return 0
}
func (m *Person) GetEmail() string {
if m != nil {
return m.Email
}
return ""
}
func (m *Person) GetPhones() []*Person_PhoneNumber {
if m != nil {
return m.Phones
}
return nil
}
func (m *Person) GetLastUpdated() *timestamp.Timestamp {
if m != nil {
return m.LastUpdated
}
return nil
}
type Person_PhoneNumber struct {
Number string `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"`
Type Person_PhoneType `protobuf:"varint,2,opt,name=type,proto3,enum=addressbook.Person_PhoneType" json:"type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Person_PhoneNumber) Reset() { *m = Person_PhoneNumber{} }
func (m *Person_PhoneNumber) String() string { return proto.CompactTextString(m) }
func (*Person_PhoneNumber) ProtoMessage() {}
func (*Person_PhoneNumber) Descriptor() ([]byte, []int) {
return fileDescriptor_1eb1a68c9dd6d429, []int{0, 0}
}
func (m *Person_PhoneNumber) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Person_PhoneNumber.Unmarshal(m, b)
}
func (m *Person_PhoneNumber) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Person_PhoneNumber.Marshal(b, m, deterministic)
}
func (m *Person_PhoneNumber) XXX_Merge(src proto.Message) {
xxx_messageInfo_Person_PhoneNumber.Merge(m, src)
}
func (m *Person_PhoneNumber) XXX_Size() int {
return xxx_messageInfo_Person_PhoneNumber.Size(m)
}
func (m *Person_PhoneNumber) XXX_DiscardUnknown() {
xxx_messageInfo_Person_PhoneNumber.DiscardUnknown(m)
}
var xxx_messageInfo_Person_PhoneNumber proto.InternalMessageInfo
func (m *Person_PhoneNumber) GetNumber() string {
if m != nil {
return m.Number
}
return ""
}
func (m *Person_PhoneNumber) GetType() Person_PhoneType {
if m != nil {
return m.Type
}
return Person_MOBILE
}
type AddressBook struct {
People []*Person `protobuf:"bytes,1,rep,name=people,proto3" json:"people,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AddressBook) Reset() { *m = AddressBook{} }
func (m *AddressBook) String() string { return proto.CompactTextString(m) }
func (*AddressBook) ProtoMessage() {}
func (*AddressBook) Descriptor() ([]byte, []int) {
return fileDescriptor_1eb1a68c9dd6d429, []int{1}
}
func (m *AddressBook) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddressBook.Unmarshal(m, b)
}
func (m *AddressBook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AddressBook.Marshal(b, m, deterministic)
}
func (m *AddressBook) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddressBook.Merge(m, src)
}
func (m *AddressBook) XXX_Size() int {
return xxx_messageInfo_AddressBook.Size(m)
}
func (m *AddressBook) XXX_DiscardUnknown() {
xxx_messageInfo_AddressBook.DiscardUnknown(m)
}
var xxx_messageInfo_AddressBook proto.InternalMessageInfo
func (m *AddressBook) GetPeople() []*Person {
if m != nil {
return m.People
}
return nil
}
func init() {
proto.RegisterEnum("addressbook.Person_PhoneType", Person_PhoneType_name, Person_PhoneType_value)
proto.RegisterType((*Person)(nil), "addressbook.Person")
proto.RegisterType((*Person_PhoneNumber)(nil), "addressbook.Person.PhoneNumber")
proto.RegisterType((*AddressBook)(nil), "addressbook.AddressBook")
}
func init() { proto.RegisterFile("addressbook.proto", fileDescriptor_1eb1a68c9dd6d429) }
var fileDescriptor_1eb1a68c9dd6d429 = []byte{
// 309 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x41, 0x4b, 0xc3, 0x40,
0x10, 0x85, 0x4d, 0x9a, 0x06, 0x3b, 0x91, 0x52, 0x47, 0x91, 0x50, 0x90, 0x86, 0x9e, 0x02, 0x85,
0x14, 0xeb, 0x41, 0x10, 0x3c, 0x58, 0x28, 0x28, 0x5a, 0x5b, 0x96, 0x8a, 0xde, 0x24, 0x21, 0x63,
0x0d, 0x4d, 0xb2, 0x4b, 0x76, 0x7b, 0xe8, 0xcf, 0xf3, 0x9f, 0x49, 0x76, 0x53, 0xe9, 0x41, 0x6f,
0x6f, 0x66, 0x3f, 0xde, 0xbe, 0x37, 0x70, 0x1a, 0xa7, 0x69, 0x45, 0x52, 0x26, 0x9c, 0x6f, 0x22,
0x51, 0x71, 0xc5, 0xd1, 0x3b, 0x58, 0xf5, 0x07, 0x6b, 0xce, 0xd7, 0x39, 0x8d, 0xf5, 0x53, 0xb2,
0xfd, 0x1c, 0xab, 0xac, 0x20, 0xa9, 0xe2, 0x42, 0x18, 0x7a, 0xf8, 0x6d, 0x83, 0xbb, 0xa4, 0x4a,
0xf2, 0x12, 0x11, 0x9c, 0x32, 0x2e, 0xc8, 0xb7, 0x02, 0x2b, 0xec, 0x30, 0xad, 0xb1, 0x0b, 0x76,
0x96, 0xfa, 0x76, 0x60, 0x85, 0x6d, 0x66, 0x67, 0x29, 0x9e, 0x43, 0x9b, 0x8a, 0x38, 0xcb, 0xfd,
0x96, 0x86, 0xcc, 0x80, 0x37, 0xe0, 0x8a, 0x2f, 0x5e, 0x92, 0xf4, 0x9d, 0xa0, 0x15, 0x7a, 0x93,
0x41, 0x74, 0x18, 0xcb, 0xd8, 0x47, 0xcb, 0x9a, 0x78, 0xd9, 0x16, 0x09, 0x55, 0xac, 0xc1, 0xf1,
0x0e, 0x4e, 0xf2, 0x58, 0xaa, 0x8f, 0xad, 0x48, 0x63, 0x45, 0xa9, 0xdf, 0x0e, 0xac, 0xd0, 0x9b,
0xf4, 0x23, 0x93, 0x3a, 0xda, 0xa7, 0x8e, 0x56, 0xfb, 0xd4, 0xcc, 0xab, 0xf9, 0x57, 0x83, 0xf7,
0xdf, 0xc1, 0x3b, 0x70, 0xc5, 0x0b, 0x70, 0x4b, 0xad, 0x9a, 0x0a, 0xcd, 0x84, 0x57, 0xe0, 0xa8,
0x9d, 0x20, 0x5d, 0xa3, 0x3b, 0xb9, 0xfc, 0x37, 0xdc, 0x6a, 0x27, 0x88, 0x69, 0x74, 0x38, 0x82,
0xce, 0xef, 0x0a, 0x01, 0xdc, 0xf9, 0x62, 0xfa, 0xf8, 0x3c, 0xeb, 0x1d, 0xe1, 0x31, 0x38, 0x0f,
0x8b, 0xf9, 0xac, 0x67, 0xd5, 0xea, 0x6d, 0xc1, 0x9e, 0x7a, 0xf6, 0xf0, 0x16, 0xbc, 0x7b, 0x63,
0x39, 0xe5, 0x7c, 0x83, 0x23, 0x70, 0x05, 0x71, 0x91, 0xd7, 0x97, 0xac, 0xaf, 0x71, 0xf6, 0xc7,
0x87, 0xac, 0x41, 0x12, 0x57, 0x77, 0xbc, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x92, 0x62,
0x76, 0xc9, 0x01, 0x00, 0x00,
}
我正在尝试这个脚本main.go
:
package main
import (
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/kurtpeek/addressbook/addressbook"
"github.com/sirupsen/logrus"
)
func main() {
person := addressbook.Person{
Name: "Boba Fett",
Email: "boba.fett@gmail.com",
Phones: []*addressbook.Person_PhoneNumber{
&addressbook.Person_PhoneNumber{
Number: "4158666171",
Type: addressbook.Person_MOBILE,
},
},
}
book := addressbook.AddressBook{
People: []*addressbook.Person{&person},
}
_, err := proto.Marshal(book)
if err != nil {
logrus.WithError(err).Fatal("marshal to ProtoBuf")
}
fmt.Printf("%+v\n", person)
}
问题是当我尝试运行它时,我得到一个AddressBook
没有实现Message
接口的错误:
> go run main.go
# command-line-arguments
./main.go:26:25: cannot use book (type addressbook.AddressBook) as type "github.com/gogo/protobuf/proto".Message in argument to "github.com/gogo/protobuf/proto".Marshal:
addressbook.AddressBook does not implement "github.com/gogo/protobuf/proto".Message (ProtoMessage method has pointer receiver)
转到 a 的定义Message
,我找到以下接口:
// Message is implemented by generated protocol buffer messages.
type Message interface {
Reset()
String() string
ProtoMessage()
}
似乎addressbook.pg.go
实现AddressBook
了所有这三种方法,所以我不明白为什么我会收到错误消息?
这是我的go.mod
,
module github.com/kurtpeek/addressbook
go 1.12
require (
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.2
github.com/sirupsen/logrus v1.4.2
)
这是我的protoc
版本(我protoc
使用安装brew install protobuf
):
> protoc --version
libprotoc 3.11.1
解决方案
proto.Marshal(&book)
在创建这样的书之前,您需要将指针传递给 proto.Marshal() 或者已经创建或创建指针:
book := &addressbook.AddressBook{
People: []*addressbook.Person{&person},
}
看第一行的 &
推荐阅读
- reactjs - 如何使用 Apollo graphql HOC 执行多个查询?
- windows - windows + D 快捷方式到底有什么作用?
- javascript - If 语句性能
- automation - 单击操作没有选项超时
- reactjs - 从当前分支中删除一个节点并添加到另一个分支
- c++ - ComplexEigenSolver 用于具有提升多精度的复杂矩阵
- elasticsearch - 如何从现有日志中提取字段(ECS 中的fluent-bit)
- javascript - Javascript 函数未运行 oninput() 或 onchange()
- visual-studio-code - 重新发布现有 VS Code 扩展所需的权限是什么以及在哪里?
- c# - 重构 C# net core 中的重复代码