3.2 KiB
3.2 KiB
protobuf
language guide(proto3)
定义message type
如下为一个定义search request message format的示例,
synatx="proto3"
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 results_per_page = 3;
}
上述示例含义如下:
synatx = "proto3":- 代表当前protobuf的language版本为
proto3 - 如果没有指定
syntax,那么protocol buffer compiler默认会假设在使用proto2
- 代表当前protobuf的language版本为
Search Request消息定义了3个fields,每个field都代表希望包含在message中的一部分数据
Assign Field Numbers
可以为message中的每个field定义一个整数,范围为[1,536,870,911],并有如下约束
- message中所有field的给定数字必须唯一
- field number
[19,000, 19,999]是为Protocol Buffer实现保留的,如果使用这些数字,protocol buffer compiler将会报错
一旦消息类型被使用后,field number就不能被改变,field number代表message wire format中的field。
如果对field的field number进行了修改,代表删除旧的field并且新建一个相同类型的field。
filed number不应该被重用。
对于频繁被设置的fields,应该将其的field number设置为[1,15]。在wire format中,field number的值越小占用空间越小。
例如,
[1,15]在编码时只占用1字节,而[16, 2047]则会占用2字节。
重复使用filed number的后果
如果重复使用field number,将会造成解码wire-format message的二义性。
对于protobuf wire format,其在编码和解码过程中,
fields的定义必须一致。
field number被限制为29bit,故而field number的最大值为536870911。
指定字段基数
在protobuf协议中,field可以为如下的集中类型
Singular
在proto3中,有两种singular field:
optional(推荐使用): 一个optional field可能有如下两种状态- 如果optional field值被设置,那么其将会被序列化到
wire中 - 如果optional field值未被设置,那么该field将会返回一个默认值,并且其不会被序列化到wire中
- 如果optional field值被设置,那么其将会被序列化到
implict(不推荐使用):一个隐式字段没有显式基数标签,并且行为如下:- 如果field为一个message type,那么其行为和
optional相同 - 如果field不是message,那么其有两种状态:
- 如果field被设置为非默认值(non-zero),其会被序列化到wire中
- 如果field被设置为zero value,那么其不会被序列化到wire中
- 如果field为一个message type,那么其行为和
相比于
implict,更推荐使用optional,使用optional能更好与proto2相兼容
repeated
代表该field可以在消息中出现0次或多次,消息出现的顺序也将被维护
map
代表field为成对的键值对