.proto文件的字段可以从零开始吗?

fad*_*bee 7 protocol-buffers

.proto示例似乎都开始将其字段编号为一个.

例如https://developers.google.com/protocol-buffers/docs/proto#simple

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}
Run Code Online (Sandbox Code Playgroud)

如果可以使用零,则它将使一些消息变小一个或多个字节(即具有一个或多个字段号为16的那些消息).

由于密钥只是(fieldnum << 3 | fieldtype)的varint编码,我无法立即看到为什么不应该使用零.

是否有理由不将字段编号设置为零?

jpa*_*jpa 6

一个非常直接的原因是零场数被拒绝protoc:

test.proto:2:28: Field numbers must be positive integers.
Run Code Online (Sandbox Code Playgroud)

至于为什么Protocol Buffers是这样设计的,我只能猜测.这样做的一个好结果是,充满零的消息将被检测为无效.它还可以用于在内部指示"无字段"作为协议缓冲区实现中的返回值.

  • 旧的 proto1 代码(从未公开发布)有评论表明标记零可能用于指示错误,尽管我从未见过实际执行此操作的代码。也许这是一个很早就被删除的功能。无论如何,对零编号字段的禁令仍然存在,并且可以说它很有用,因为它可以捕获那些无意识地对 protobuf 消息进行零填充并期望它们仍然能够正确解析的人(这种情况经常发生!)。 (2认同)

小智 5

分配标签

如您所见,消息定义中的每个字段都有一个唯一的编号标签。这些标签用于在消息二进制格式中标识您的字段,一旦您的消息类型被使用,就不应更改。请注意,值在 1 到 15 范围内的标签占用一个字节进行编码,包括标识号和字段类型(您可以在协议缓冲区编码中找到更多相关信息)。16 到 2047 范围内的标签占用两个字节。因此,您应该为非常频繁出现的消息元素保留标签 1 到 15。请记住为将来可能添加的频繁出现的元素留出一些空间。

您可以指定的最小标记号是 1,最大的是 2 29 -1 或 536,870,911。您也不能使用数字 19000 到 19999(FieldDescriptor::kFirstReservedNumber 到 FieldDescriptor::kLastReservedNumber),因为它们是为 Protocol Buffers 实现保留的 - 如果您在 .proto 中使用这些保留数字之一,protocol buffer 编译器会抱怨。同样,您不能使用任何以前保留的标签。

https://developers.google.com/protocol-buffers/docs/proto

就像文档说的,0 不能被检测到。