Protocol Buffers學習(4):更多消息類型

介紹一下消息的不一樣類型和引用javascript

使用複雜消息類型

您可使用其餘消息類型做爲字段類型。例如,假設你想在每一個SearchResponse消息中包含Result消息,您能夠在同一個.proto中定義一個Result消息類型,而後在SearchResponse中指定一個Result類型的字段:java

message SearchResponse {
  repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}複製代碼

引入其餘消息文件

在上述示例中,Result消息類型與SearchResponse在相同的文件中定義, 若是要使用的消息類型已經在另外一個.proto文件中定義了怎麼解決呢?編程

你能夠經過import引入其餘的.proto文件:編程語言

import "myproject/other_protos.proto";複製代碼

注意ui

接上邊的例子,假如a.proto引入了b.proto,可是b.proto更換了位置,路徑變成了test/b.proto(隨便舉例),咱們有兩種解決辦法:google

  1. 修改a.proto中的import語句,直接import "test/b.proto"
  2. b.proto文件原來的位置,建立一個b.proto文件,文件內容爲import public "test/b.proto",就能夠了

importproto2proto3都適用編碼

嵌套類型

您能夠在其餘消息類型中定義和使用消息類型,以下,Result消息定義在SearchResponse消息中:url

message SearchResponse {
  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
  repeated Result results = 1;
}複製代碼

若是想重複使用Result,能夠用Parent.Type的方式使用:spa

message AnotherResponse {
    SearchResponse.Result res = 1;
}複製代碼

修改更新現有的消息格式

修改時要注意的規則:code

  1. 不要改變已經存在字段的標籤
  2. 添加一個字段時,舊的消息將會收到這個字段的默認值
  3. 刪除一個字段時,記得把該字段的標籤添加到reserved
  4. int32,uint32,int64,uint64和bool都是兼容的。這意味着您能夠將這些類型之一的字段更改成另外一個,而不會破壞前向或後向兼容性。轉換過程至關於C ++中將該數字轉換爲該類型(例如,若是將64位數字讀爲int32, 它將被截斷到32位)
  5. sint32和sint64相互兼容,但與其餘整數類型不兼容
  6. 只要字節是有效的UTF-8,字符串和字節是兼容的
  7. 嵌套消息(message)與包含消息的編碼版本的字節(bytes)兼容【表述不清,歡迎你們評論指正】
  8. fixed32與sfixed32兼容,fixed64與sfixed64兼容
  9. 枚舉兼容int32,uint32,int64和uint64(請注意,若是值不合適,那麼值將被截斷)。 可是請注意,客戶端代碼能夠在消息反序列化時對它們進行不一樣的處理:例如,消息中將保留沒法識別的proto3枚舉類型,可是當消息反序列化時,如何處理和使用的編程語言相關。 Int字段始終保持其值

Any類型

any類型時谷歌protobuf內置的一個類型,通用類型,使用的時候須要導入google/protbuf/any.proto

import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}複製代碼

Oneof類型

Oneof結構中有多個字段,可是同一時刻只有一個字段生效

定義oneof結構

message SampleMessage {
  oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
  }
}複製代碼

oneof中能夠是任意類型,除了repeated 字段

生成代碼以後,也會對oneof字段生成getter,setter方法,可是出來的值須要你本身判斷一下

Maps 類型

若是你要定義一個map,protobuf提供了一個語法:

map<key_type, value_type> map_field = N;複製代碼

例如

map<string, Project> projects = 3;複製代碼

注意事項

  • Map字段不能是repeated
  • Map中的集合是無序的
  • .proto文件生成時,map按key排序
  • 解析或者合併時,後邊的會覆蓋前邊的

packages語法

你能夠添加一個可選標識package.proto文件中。用來防止命名衝突

package foo.bar;
message Open { ... }複製代碼

在使用這條消息的時候須要加上package名字

message Foo {
  ...
  foo.bar.Open open = 1;
  ...
}複製代碼
相關文章
相關標籤/搜索