Protocol Buffers定义消息类型

本文介绍了Protocol Buffers(protobuf)中定义消息类型的语法,包括指定字段类型、分配字段编号、字段规则以及如何添加消息类型和注释。重点讨论了字段的单数和重复规则,以及编译器生成的代码。此外,还提到了保留字段的重要性,以避免数据损坏和版本兼容问题。编译.proto文件会产生不同编程语言的代码,方便在应用中使用消息类型。
摘要由CSDN通过智能技术生成

目录

指定字段类型

分配字段编号

指定字段规则

添加更多消息类型

添加注释

保留字段

编译器将生成什么?


首先让我们看一个非常简单的例子。假设你要定义一个分页搜索请求消息格式,其中每个搜索请求都有一个查询字符串、你感兴趣的特定结果页面以及每页的多个结果。这是.proto你用来定义消息类型的文件。

syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
  • 文件的第一行指定你使用的是proto3语法:如果你不这样做,Protocol Buffers编译器将假定你使用的是proto2。这必须是文件的第一个非空、非注释行。
  • SearchRequest消息定义指定了三个字段(名称/值对),每个字段用于你希望包含在此类消息中的每条数据。每个字段都有一个名称和一个类型。

指定字段类型

在上面的示例中,所有字段都是标量类型:两个整数(page_numberresult_per_page)和一个字符串(query)。但是,你也可以为字段指定复合类型,包括枚举和其他消息类型。

分配字段编号

消息定义中的每个字段都有一个唯一的编号。这些字段编号用于在消息二进制格式中标识你的字段,并且在使用你的消息类型后不应更改。

请注意,1 到 15 范围内的字段编号需要一个字节进行编码,包括字段编号和字段类型(你可以在Protocol Buffer Encoding中找到有关此的更多信息)。16 到 2047 范围内的字段编号占用两个字节。因此,你应该为非常频繁出现的消息元素保留数字 1 到 15。请记住为将来可能添加的频繁出现的元素留出一些空间。

你可以指定的最小字段编号是 1,最大的是 2 29 - 1,即 536,870,911。你也不能使用数字 19000 到 19999(FieldDescriptor::kFirstReservedNumberFieldDescriptor::kLastReservedNumber),因为它们是为 Protocol Buffers 实现保留的 - 如果你在.proto. 同样,你不能使用任何以前保留的字段编号。

指定字段规则

消息字段可以是以下之一:

  • 单数:符合语法规则的消息可以有零个或一个此字段(但不能超过一个)。这是 proto3 语法的默认字段规则。
  • repeated:该字段可以在符合语法规则的消息中重复任意次数(包括零次)。重复值的顺序将被保留。

在 proto3 中,repeated标量数值类型的字段packed默认使用编码。

你可以在Protocol Buffer Encoding中找到有关packed编码的更多信息。

添加更多消息类型

可以在单个.proto文件中定义多种消息类型。如果你要定义多个相关消息,这很有用——例如,如果你想定义与你的SearchResponse消息类型相对应的回复消息格式,你可以将其添加到相同的.proto:

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}
message SearchResponse {
...
}

添加注释

要向.proto文件添加注释,请使用 C/C++ 样式///* ... */语法。

/* SearchRequest represents a search query, with pagination options to
 * indicate which results to include in the response. */
message SearchRequest {
string query = 1;
int32 page_number = 2;  // Which page number do we want?
int32 result_per_page = 3;  // Number of results to return per page.
}

保留字段

如果你通过完全删除某个字段或将其注释掉来更新消息类型,未来的用户可以在对类型进行自己的更新时重用该字段编号。如果他们稍后加载相同的旧版本,这可能会导致严重问题.proto,包括数据损坏、隐私错误等。确保不会发生这种情况的一种方法是指定已删除字段的字段编号(和/或名称,这也可能导致 JSON 序列化问题)为reserved. 如果将来有任何用户尝试使用这些字段标识符,protocol buffer 编译器会报错。

message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}

请注意,你不能在同一reserved语句中混合字段名称和字段编号。

编译器将生成什么?

当你编译一个.proto文件时,编译器会以你选择的语言生成代码,你需要使用文件中描述的消息类型,包括获取和设置字段值,将消息序列化到输出流,并从输入流中解析你的消息。

  • 对于C++,编译器从每个 .proto 生成一个.hand.cc文件,并为文件中描述的每种消息类型提供一个类。
  • 对于Java,编译器会.java为每种消息类型生成一个包含类的文件,以及Builder用于创建消息类实例的特殊类。
  • 对于Kotlin,除了 Java 生成的代码之外,编译器还会.kt为每种消息类型生成一个文件,其中包含可用于简化创建消息实例的 DSL。
  • Python有点不同——Python 编译器会生成一个模块*,*.proto其中包含你的 .
  • 对于Go,编译器会为.pb.go文件中的每个消息类型生成一个文件类型。
  • 对于Ruby,编译器会生成一个.rb带有 Ruby 模块的文件,其中包含你的消息类型。
  • 对于Objective-C,编译器从每个 .proto 生成一个pbobjc.handpbobjc.m文件.proto,并为文件中描述的每种消息类型提供一个类。
  • 对于C#,编译器会.cs从 每个 .proto 生成一个文件.proto,其中包含文件中描述的每种消息类型的类。
  • 对于Dart,编译器会为文件中的每种消息类型生成一个.pb.dart带有类的文件。

你可以按照所选语言的教程(即将推出 proto3 版本)了解有关使用每种语言的 API 的更多信息。有关更多 API 详细信息,请参阅相关API 参考(proto3 版本也即将推出)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值