protocol buffer 的proto文件
1,支持的基本类型
.proto Type | Notes | C++ Type | Java Type |
---|---|---|---|
double | double | double | |
float | float | float | |
int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int |
int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long |
uint32 | Uses variable-length encoding. | uint32 | int[1] |
uint64 | Uses variable-length encoding. | uint64 | long[1] |
sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int |
sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long |
fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 228. | uint32 | int[1] |
fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 256. | uint64 | long[1] |
sfixed32 | Always four bytes. | int32 | int |
sfixed64 | Always eight bytes. | int64 | long |
bool | bool | boolean | |
string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String |
bytes | May contain any arbitrary sequence of bytes. | string | ByteString |
2,Optional Fields And Default Values 可选字段和默认值
As mentioned above, elements in a message description can be labeled optional
. A well-formed message may or may not contain an optional element. When a message is parsed, if it does not contain an optional element, the corresponding field in
the parsed object is set to the default value for that field. The default value can be specified as part of the message description. For example, let's say you want to provide a default value of 10 for a
SearchRequest
's result_per_page
value.
消息的字段类型可以标记为optional.一个定义良好的消息一般不会包含可选字段。当处理一个消息的时候,如果数据中不存在该字段,相应的字段会使用默认值。这个默认值可以在消息描述里面写。例如:
optional int32 result_per_page = 3 [default = 10];
If the default value is not specified for an optional element, a type-specific default value is used instead: for strings, the default value is the empty string. For bools, the default value is false. For numeric types, the default value is zero. For enums, the default value is the first value listed in the enum's type definition.
如果没有定义默认值,那么系统会给每种类型设置默认值:字符串,默认值是空串。bool,默认为false。数值类型,默认0.枚举类型,默认是枚举的以一个值。
3,Using Other Message Types,在消息中使用其它消息类型
You can use other message types as field types. For example, let's say you wanted to include
Result
messages in each SearchResponse
message – to do this, you can define a
Result
message type in the same .proto
and then specify a field of type
Result
in SearchResponse
:
你可以使用其他消息类型当作消息的类型。
message SearchResponse { repeated Result result = 1; } message Result { required string url = 1; optional string title = 2; repeated string snippets = 3; }
4,Assigning Tags 字段序号
As you can see, each field in the message definition has a unique numbered tag. These tags are used to identify your fields in the message binary format, and should not be changed once your message type is in use. Note that tags with values in the range 1 through 15 take one byte to encode. Tags in the range 16 through 2047 take two bytes. So you should reserve the tags 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.
The smallest tag number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 though 19999 (FieldDescriptor::kFirstReservedNumber
through
FieldDescriptor::kLastReservedNumber
), as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your
.proto
.
你会发现消息定义中每个字段都有一个唯一数字标签。这些标签用来在二进制数据中识别每个字段,而且如果已经开始使用最好不要改变标签。1到15的标签需要1字节编码。标签在16到2047需要2字节。所以你要把1到15的标签留给常用的字段。最小标签是1,最大2的29次方减一。你不能使用19000到19999范围,这个是保留给protocolbuffer内部使用的。
5,Specifying Field Rules 字段声明规则
You specify that message fields are one of the following:
required
: a well-formed message must have exactly one of this field.optional
: a well-formed message can have zero or one of this field (but not more than one).repeated
: this field can be repeated any number of times (including zero) in a well-formed message. The order of the repeated values will be preserved.
你可以使用一下声明:
* required:一个良好定义的消息必须至少要有一个这种类型的字段。
* optional: 一个良好定义的消息可以有0个或者一个这种类型的字段(不能超过1个)。
* repeated:这种类型的字段可以重复0到若干次。重复的值的顺序。。!
For historical reasons, repeated
fields of basic numeric types aren't encoded as efficiently as they could be. New code should use the special option
[packed=true]
to get a more efficient encoding. For example:
repeated int32 samples = 4 [packed=true];
Required Is Forever You should be very careful about marking fields as
required
. If at some point you wish to stop writing or sending a required field, it will be problematic to change the field to an optional field – old readers will consider messages without this field to be incomplete and may reject or drop them
unintentionally. You should consider writing application-specific custom validation routines for your buffers instead. Some engineers at Google have come to the conclusion that using
required
does more harm than good; they prefer to use only optional
and
repeated
. However, this view is not universal.
Required 是永远存在的。
你要小心定义required类型的字段。一旦你想修改required成optional会有麻烦-因为旧的读者还会按照required的方式去读你的新数据。