protobuf语法简介2html
1.optional的字段和默认值api
如上所述,消息描述中的一个元素能够被标记为“可选的”(optional)。一个格式良好的消息能够包含0个或一个optional的元素。当解析消息时,若是它不包含optional的元素值,那么解析出来的对象中的对应字段就被置为默认值。默认值能够在消息描述文件中指定。例如,要为 SearchRequest消息的result_per_page字段指定默认值10,在定义消息格式时以下所示:ui
optional int32 result_per_page = 3 [default = 10];google |
若是没有为optional的元素指定默认值,就会使用与特定类型相关的默认值:对string来讲,默认值是空字符串。对bool来讲,默认值是false。对数值类型来讲,默认值是0。对枚举来讲,默认值是枚举类型定义中的第一个值。编码
2.枚举url
当须要定义一个消息类型的时候,可能想为一个字段指定某“预约义值序列”中的一个值。例如,假设要为每个SearchRequest消息添加一个 corpus字段,而corpus的值多是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一个。其实能够很容易地实现这一点:经过向消息定义中添加一个枚举(enum)就能够了。一个enum类型的字段只能用指定的常量集中的一个值做为其值(若是尝试指定不一样的值,解析器就会把它看成一个未知的字段来对待)。在下面的例子中,在消息格式中添加了一个叫作Corpus的枚举类型——它含有全部可能的值 ——以及一个类型为Corpus的字段:spa
message SearchRequest {命令行 required string query = 1;code optional int32 page_number = 2;orm optional int32 result_per_page = 3 [default = 10]; enum Corpus { UNIVERSAL = 0; WEB = 1; IMAGES = 2; } optional Corpus corpus = 4 [default = IMAGES ]; } |
枚举常量必须在32位整型值的范围内。由于enum值是使用可变编码方式的,对负数不够高效,所以不推荐在enum中使用负数。如上例所示,能够在一个消息定义的内部或外部定义枚举——这些枚举能够在.proto文件中的任何消息定义里重用。固然也能够在一个消息中声明一个枚举类型,而在另外一个不一样的消息中使用它——采用MessageType.EnumType的语法格式。
当对一个使用了枚举的.proto文件运行protocol buffer编译器的时候,生成的代码中将有一个对应的enum(对Java或C++来讲),或者一个特殊的EnumDescriptor类(对 Python来讲),它被用来在运行时生成的类中建立一系列的整型值符号常量(symbolic constants)。
3.使用其余消息类型
你能够将其余消息类型用做字段类型。例如,假设在每个SearchResponse消息中包含Result消息,此时能够在相同的.proto文件中定义一个Result消息类型,而后在SearchResponse消息中指定一个Result类型的字段,如:
message SearchResponse { repeated Result result = 1; } message Result { required string url = 1; optional string title = 2; repeated string snippets = 3; } |
4.导入定义
在上面的例子中,Result消息类型与SearchResponse是定义在同一文件中的。若是想要使用的消息类型已经在其余.proto文件中已经定义过了呢?
你能够经过导入(importing)其余.proto文件中的定义来使用它们。要导入其余.proto文件的定义,你须要在你的文件中添加一个导入声明,如:
import "myproject/other_protos.proto"; |
protocol编译器就会在一系列目录中查找须要被导入的文件,这些目录经过protocol编译器的命令行参数-I/–import_path指定。若是不提供参数,编译器就在其调用目录下查找。
5.嵌套类型
你能够在其余消息类型中定义、使用消息类型,在下面的例子中,Result消息就定义在SearchResponse消息内,如:
message SearchResponse { message Result { required string url = 1; optional string title = 2; repeated string snippets = 3; } repeated Result result = 1; } |
若是你想在它的父消息类型的外部重用这个消息类型,你须要以Parent.Type的形式使用它,如:
message SomeOtherMessage { optional SearchResponse.Result result = 1; } |
固然,你也能够将消息嵌套任意多层,如:
message Outer { // Level 0 message MiddleAA { // Level 1 message Inner { // Level 2 required int64 ival = 1; optional bool booly = 2; } } message MiddleBB { // Level 1 message Inner { // Level 2 required int32 ival = 1; optional bool booly = 2; } } } |
原文
http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/reference/overview.html
http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html