protobuf語法簡介2
1.optional的字段和默認值
如上所述,消息描述中的一個元素可以被標記為“可選的”(optional)。一個格式良好的消息可以包含0個或一個optional的元素。當解析消息時,如果它不包含optional的元素值,那么解析出來的對象中的對應字段就被置為默認值。默認值可以在消息描述文件中指定。例如,要為 SearchRequest消息的result_per_page字段指定默認值10,在定義消息格式時如下所示:
optional int32 result_per_page = 3 [default = 10]; |
如果沒有為optional的元素指定默認值,就會使用與特定類型相關的默認值:對string來說,默認值是空字符串。對bool來說,默認值是false。對數值類型來說,默認值是0。對枚舉來說,默認值是枚舉類型定義中的第一個值。
2.枚舉
當需要定義一個消息類型的時候,可能想為一個字段指定某“預定義值序列”中的一個值。例如,假設要為每一個SearchRequest消息添加一個 corpus字段,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一個。其實可以很容易地實現這一點:通過向消息定義中添加一個枚舉(enum)就可以了。一個enum類型的字段只能用指定的常量集中的一個值作為其值(如果嘗試指定不同的值,解析器就會把它當作一個未知的字段來對待)。在下面的例子中,在消息格式中添加了一個叫做Corpus的枚舉類型——它含有所有可能的值 ——以及一個類型為Corpus的字段:
message SearchRequest { required string query = 1; optional int32 page_number = 2; 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