阅读Google Protocol Buffers 指南,整理pb语法
2017-07-22 11:05
507 查看
官方网站:
https://developers.google.com/protocol-buffers/docs/proto3
1、简单定义一个Message 类型
pb语法文件以"*.proto"为文件扩展名。在版本proto3文件头需要包含版本类型“syntax = "proto3";”,缺省情况为proto2类型。
官方示例:
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
message为类标识符
SearchRequest为类名
string/int32为字段类型
query/page_number/result_per_page为字段名称
1/2/3为编号标签,用于序列化后内容标识,序号1~15需要1个字节,16~2047需要2个字节,最小编号为1,最大编号229-1或536870911。19000~19999系统预留,不可用。
2、字段描述规则
字段的规则主要分为单数和复数,用于描述字段是否是单个字段还是数组。默认情况下字段定义都是单数“singular”,如果需要定义数组需要在字段类型前面加“
3、添加注释
可以在字段定义结束后加“//”注释,该注释会在生成的字段代码中。
官方示例:
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.
}
4、保留字段
编号定义后,无法更改,如果需要重新定义类型或删除旧的类型,需要在序列化文件中占位原定义的类型。这样才能保证更改后数据正常反序列化,并对以前数据兼容。否则数据格式不正确后,将导致对更改前的数据反序列化出错。
官方示例:
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
5、字段类型
string, 默认值为空字符串.
bytes, 默认值为空字节数组.
bool, 默认值为false.
数值类型, 默认值为0.
enums, 从0开始的枚举.
message对象列, 没有设置默认值,根据不同语言给定相应的规则
int32,uint32,int64,uint64、bool和枚举是兼容的,可以相互转换,更改字段类型后,可以向前和向后兼容,但会强制类型转化,会截断数值,如64变32位,以前的数据会只被读取32位值。
sint32和sint64彼此兼容,fixed32与sfixed32彼此兼容。
6、枚举类型的定义
官方示例:
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;
}
enum为枚举关键字
enum类型必须定义枚举值0.
一般情况下不允许同值枚举存在。如果需要增加同值枚举需要添加“option allow_alias = true;”
官方示例:
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
7、引用其他文件
官方示例:
import "myproject/other_protos.proto";
在多次引用过程中也可以控制引用的作用域。加关键字“public”将可以被下下次引用使用。
官方示例:
// new.proto // All definitions are moved here
old 引用了public new和other,other只能在old里面使用。
https://developers.google.com/protocol-buffers/docs/proto3
1、简单定义一个Message 类型
pb语法文件以"*.proto"为文件扩展名。在版本proto3文件头需要包含版本类型“syntax = "proto3";”,缺省情况为proto2类型。
官方示例:
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
message为类标识符
SearchRequest为类名
string/int32为字段类型
query/page_number/result_per_page为字段名称
1/2/3为编号标签,用于序列化后内容标识,序号1~15需要1个字节,16~2047需要2个字节,最小编号为1,最大编号229-1或536870911。19000~19999系统预留,不可用。
2、字段描述规则
字段的规则主要分为单数和复数,用于描述字段是否是单个字段还是数组。默认情况下字段定义都是单数“singular”,如果需要定义数组需要在字段类型前面加“
repeated”。
3、添加注释
可以在字段定义结束后加“//”注释,该注释会在生成的字段代码中。
官方示例:
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.
}
4、保留字段
编号定义后,无法更改,如果需要重新定义类型或删除旧的类型,需要在序列化文件中占位原定义的类型。这样才能保证更改后数据正常反序列化,并对以前数据兼容。否则数据格式不正确后,将导致对更改前的数据反序列化出错。
官方示例:
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
5、字段类型
.proto Type | Notes | C++ Type | Java Type | Python Type[2] | Go Type | Ruby Type | C# Type | PHP Type |
---|---|---|---|---|---|---|---|---|
double | double | double | float | float64 | Float | double | float | |
float | float | float | float | float32 | 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 | int | int32 | Fixnum or Bignum (as required) | int | integer |
int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
uint32 | Uses variable-length encoding. | uint32 | int[1] | int/long[3] | uint32 | Fixnum or Bignum (as required) | uint | integer |
uint64 | Uses variable-length encoding. | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] |
sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer |
sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 228. | uint32 | int[1] | int | uint32 | Fixnum or Bignum (as required) | uint | integer |
fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 256. | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] |
sfixed32 | Always four bytes. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer |
sfixed64 | Always eight bytes. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
bool | bool | boolean | bool | bool | TrueClass/FalseClass | bool | boolean | |
string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode[4] | string | String (UTF-8) | string | string |
bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | String (ASCII-8BIT) | ByteString | string |
bytes, 默认值为空字节数组.
bool, 默认值为false.
数值类型, 默认值为0.
enums, 从0开始的枚举.
message对象列, 没有设置默认值,根据不同语言给定相应的规则
int32,uint32,int64,uint64、bool和枚举是兼容的,可以相互转换,更改字段类型后,可以向前和向后兼容,但会强制类型转化,会截断数值,如64变32位,以前的数据会只被读取32位值。
sint32和sint64彼此兼容,fixed32与sfixed32彼此兼容。
6、枚举类型的定义
官方示例:
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;
}
enum为枚举关键字
enum类型必须定义枚举值0.
一般情况下不允许同值枚举存在。如果需要增加同值枚举需要添加“option allow_alias = true;”
官方示例:
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
7、引用其他文件
官方示例:
import "myproject/other_protos.proto";
在多次引用过程中也可以控制引用的作用域。加关键字“public”将可以被下下次引用使用。
官方示例:
// new.proto // All definitions are moved here
// old.proto // This is the proto that all clients are importing. import public "new.proto"; import "other.proto";
old 引用了public new和other,other只能在old里面使用。
// client.proto import "old.proto"; // You use definitions from old.proto and new.proto, but not other.proto client引用了old,因为new在old引用中是public 的,所以client是可以使用new. 但不能使用other. 7、嵌套类型 message 可以嵌套多层message. message 可以嵌套 enum. 官方示例: message Outer { // Level 0 message MiddleAA { // Level 1 message Inner { // Level 2 int64 ival = 1; bool booly = 2; } } message MiddleBB { // Level 1 message Inner { // Level 2 int32 ival = 1; bool booly = 2; } } } 8、Any类型 PB支持未知类型。该类型包含任意序列化的消息作为字节,以及一个充当全局唯一标识符并解析为该消息类型的URL。要使用Any类型,您需要导入google / protobuf / any.proto。 官方示例: import "google/protobuf/any.proto"; message ErrorStatus { string message = 1; repeated google.protobuf.Any details = 2; } 9、Oneof类型 如果有一个包含多个字段的消息,并且最多可以同时设置一个字段,则可以通过使用该功能强制执行此行为并节省内存。 Oneof字段就像常规字段,除了一个共享内存中的所有字段,最多可以同时设置一个字段。 设置任何成员自动清除所有其他成员。 可以根据选择的语言检查使用case()或WhereOneof()方法设置一个值中的值。 官方示例: message SampleMessage { oneof test_oneof { string name = 4; SubMessage sub_message = 9; } } 10、Map类型 语法规则为: map<key_type, value_type> map_field = N; 示例: map<string, Project> projects = 3; 11、包Package 我们可以在“.proto”文件中定义包,可以防止类的名称冲突,在我们使用过程可以加包名来定义字段类型。 官方示例: package foo.bar; message Open { ... } 使用时, message Foo { ... foo.bar.Open open = 1; ... }
相关文章推荐
- Google Protocol Buffers 语法整理
- google protocol buffers 开发者指南
- Google Protocol Buffers (一个客户端与服务器协议生成工具)
- Google Protocol Buffers介绍和总结
- Google C++ 风格指南内容整理
- Google Protocol Buffers 快速入门(带生成C#源码的方法)
- Protocol Buffers proto语言语法说明
- Google Protocol Buffers 实用技术:解析.proto文件和任意数据文件
- Google Protocol Buffers安装、使用二三事
- Google C++ 风格指南内容整理
- Google Protocol Buffers 之.Net应用
- 试用GOOGLE PROTOCOL BUFFERS( 比XML快20~100倍, 支持序列化数据 )
- Google应用指南:高级搜索语法
- 在Unity3d中使用Google.ProtocolBuffers
- Google 开源项目风格指南阅读笔记(C++版)
- google入侵语法整理
- 为什么要使用Google Protocol Buffers
- Google Protocol Buffers 反序列化 转
- Google Protocol Buffers 学习笔记
- Google Protocol Buffers浅析