protobuf-2 消息类型

基本数据类型

syntax = "proto3";

// 所有基本数据类型
// protoc --go_out=. scalar.proto
option go_package = "../service";

message scalar{
  double filed1 = 1;  //float64
  float field2 = 2;   //float32
  int32 field3 = 3;   //int32
  int64 field4 = 4;   //int64
  uint32 field5 = 5;  //uint32
  uint64 field6 = 6;  //uint64
  sint32 field7 = 7;  //int32
  sint64 field8 = 8;  //int64
  fixed32 field9 = 9; //uint32
  fixed64 field10 = 10; //uint64
  sfixed32 field11 = 11; //int32
  sfixed64 field12 = 12; //int64
  bool field13 = 13;  //bool
  string  field14 = 14; //string
  bytes field15 = 15;  //[]byte
}

生成的go代码
image.png

枚举类型

syntax = "proto3";

// protoc --go_out=. enumerations.proto
option go_package = "../service";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}

生成的go代码

image.png

image.png

其他消息类型

syntax = "proto3";

// protoc --go_out=. other_message_type.proto
option go_package = "../service";

message SearchResponse {
  repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

如果使用的类型定义在其他proto文件中,需要import导入

image.png

image.png

嵌套类型

syntax = "proto3";

// protoc --go_out=. nested.proto
option go_package = "../service";

message NestedSearchResponse {
  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
  repeated Result results = 1;
}

image.png

image.png

更新消息类型

有时候你不得不修改正在使用的proto文件,比如为类型增加一个字段,protobuf支持这种修改而不影响已有的服务,不过你需要遵循一定的规则:

  • 不要改变已有字段的字段编号
  • 当你增加一个新的字段的时候,老系统序列化后的数据依然可以被你的新的格式所解析,只不过你需要处理新加字段的缺省值。 老系统也能解析你信息的值,新加字段只不过被丢弃了
  • 字段也可以被移除,但是建议你Reserved这个字段,避免将来会使用这个字段
  • int32, uint32, int64, uint64 和 bool类型都是兼容的
  • sint32 和 sint64兼容,但是不和其它整数类型兼容
  • string 和 bytes兼容,如果 bytes 是合法的UTF-8 bytes的话
  • 嵌入类型和bytes兼容,如果bytes包含一个消息的编码版本的话
  • fixed32和sfixed32, fixed64和sfixed64
  • enum和int32, uint32, int64, uint64格式兼容
  • 把单一一个值改变成一个新的oneof类型的一个成员是安全和二进制兼容的。把一组字段变成一个新的oneof字段也是安全的,如果你确保这一组字段最多只会设置一个。把一个字段移动到一个已存在的oneof字段是不安全的

常见问题

1.protoc-gen-go: unable to determine Go import path for xxx

image.png

在新版中,必须指定 go_package

// 通过分号分割
// 前半部分是path 表示生成文件的存放目录
// 后半部分是生成go文件的包名
option go_package="example.com/protos/foo;package_name";

具体参考这里 https://github.com/golang/pro...

参考

后端程序员

144 声望
1 粉丝
0 条评论
推荐阅读
GO 实现优先队列
在php中提供了SplPriorityQueue来实现优先队列操作。在Go中,虽然没有直接提供优先队列的实现,不过通过标准库container/heap可以很方便的实现一个简单的优先队列。

tim_xiao阅读 405

IM通讯协议专题学习(七):手把手教你如何在NodeJS中从零使用Protobuf
Protobuf最大的特点是数据格式拥有极高的压缩比,这在移动互联时代是极具价值的(因为移动网络流量到目前为止仍然昂贵的),如果你的APP能比竞品更省流量,无疑这也将成为您产品的亮点之一。

JackJiang1阅读 426

封面图
写给go开发者的gRPC教程-通信模式
本篇为【写给go开发者的gRPC教程系列】第二篇第一篇:protobuf基础第二篇:通信模式上一篇介绍了如何编写 protobuf 的 idl,并使用 idl 生成了 gRPC 的代码,现在来看看如何编写客户端和服务端的代码Simple RPC (...

liangwt1阅读 827

封面图
go精通protobuf连载三:protobuf使用示例,深入了解protoc命令
一、protobuf的使用分两步需要使用者在.proto文件中定义消息类型。使用protoc编译器根据.proto文件生成相应语言的代码。二、定义proto消息类型目前protobuf官方文档最新是v3版本,我们使用也是v3版本。[链接]对应...

海生阅读 936

go精通protobuf连载一:安装protobuf与protoc-gen-go
protobuf是一种与语言无关、与平台无关的可扩展的插件,用于序列化结构化数据。只需要定义一下protobuf结构的文件 .proto 然后就可以使用protoc 命令生成对应的编程语言的结构的文件。

海生阅读 818

写给go开发者的gRPC教程-protobuf基础
序列化协议。gRPC使用protobuf,首先使用protobuf定义服务,然后使用这个文件来生成客户端和服务端的代码。因为pb是跨语言的,因此即使服务端和客户端语言并不一致也是可以互相序列化和反序列化的

liangwt阅读 806评论 1

封面图
protocol-buffers namespace conflict
在运行grpc服务,加载*.pb.go时可能会报冲突错误,如文件名命名冲突:其实针对文件名冲突的错误处理开发者有移除过"文件冲突检测":[链接]后来发现有问题又加上了"文件冲突检测":[链接]

AVOli阅读 790

后端程序员

144 声望
1 粉丝
宣传栏