二.protobuf3數據類型


定義數據類型

  首先讓我們看一個非常簡單的例子。假設您想要定義搜索請求消息格式,其中每個搜索請求都有一個查詢字符串、您感興趣的特定結果頁面以及每頁的結果數量。這是用來定義消息類型的.proto文件。

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

  文件的第一行指定您正在使用proto 3語法:如果不這樣做,協議緩沖區編譯器將假設您正在使用proto 2。這必須是文件的第一個非空的非注釋行。

  SearchRequest消息定義指定了三個字段(名稱/值對),每一個字段對應於要包含在這種類型的消息中的數據。每個字段都有一個名稱和一個類型。

指定字段類型

  在上例中,所有字段都是標量類型:兩個整數(page_number和result_per_page)和一個字符串(query)。但是,您也可以為字段指定復合類型,包括枚舉和其他消息類型。

分配字段編號

  如您所見,消息定義中的每個字段都有一個唯一的編號。這些字段編號用於以二進制格式標識您的字段,一旦您的消息類型被使用,就不應該被更改。請注意,1到15范圍內的字段編號需要一個字節來編碼,包括字段編號和字段類型(您可以在協議緩沖區編碼中找到更多信息)。16到2047范圍內的字段編號需要兩個字節。因此,您應該為經常出現的消息元素保留數字1到15。記住為將來可能添加的頻繁出現的元素留出一些空間。

  您可以指定的最小字段編號為1,最大字段編號為229 - 1,即536,870,911。但是不能使用數字19000到19999 ( FieldDescriptor::kFirstReservedNumber 到FieldDescriptor::kLastReservedNumber),因為它們是為協議緩沖區實現而保留的-如果您在 .proto文件中使用這些保留的數字之一,協議緩沖區編譯器就會報錯。同樣,您也不能使用任何保留字段。

指定字段規則

  消息字段可以是以下字段之一:

singular: 可以有零個或其中一個字段(但不超過一個)。

repeated: 該字段可以重復任意次數(包括零次)。重復值的順序將被保留。

  在proto 3中,可擴展的repeated字段為數字類型的默認編碼。

  您可以在協議緩沖區編碼中找到更多關於打包編碼的信息。

添加更多消息類型

  可以在單個.proto中定義多種消息類型。如果您要定義多個相關消息,這很有用——例如,如果您想定義與搜索響應消息類型相對應的回復消息格式,可以將其添加到該.proto中:

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
 ...
}

添加注釋

為你的.proto 添加注釋,使用 C/C++風格的 // 或者 /* ... */ 語法.

/* SearchRequest represents a search query, with pagination options to
 * indicate which results to include in the response. */

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.
}

保留字段

  如果通過完全刪除某個字段或對其進行注釋來更新消息類型,將來的用戶可以在對該類型進行自己的更新時重用該字段編號。如果他們以后加載舊版本的相同.proto文件,這可能會導致嚴重的問題 ,包括數據損壞、隱私漏洞等。確保不會發生這種情況的解決方案是指定已刪除字段的字段編號(and/or名稱,這也可能導致JSON序列化問題)是保留的。如果將來有任何用戶試圖使用這些字段標識符,協議緩沖區編譯器會報錯。

message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}

  請注意,不能在同一保留語句中混合字段名和字段編號。

從.proto文件中生成了什么?

  在.proto上運行協議緩沖區編譯器時,編譯器用您指定的編程語言生成代碼,您需要使用您在文件中描述的消息類型,包括獲取和設置字段值,將消息序列化為輸出流,以及從輸入流解析消息。

  對於C++,編譯器會從每個 .proto文件生成一個 .h and .cc文件, 文件中描述的每種消息類型都有一個類。

  對於Java,編譯器為每個消息類型生成一個Java文件,其中包括每個類的定義,以及用於創建消息類實例的特殊構建器類。

  Python有點不同,Python編譯器生成一個模塊,其中包含中每種消息類型的靜態描述符,然后與元類一起使用,在運行時創建必要的Python數據訪問類。

  對於Go, 編譯器生成一個.pb.go文件,其中包含文件中每種消息類型的類型。

  對於Ruby, 編譯器生成一個.rb文件帶有包含消息類型的Ruby模塊。

  對於Objective-C, 編譯器為每個.proto文件中生成一個pbobjc.h和pbobjc.m文件,文件中描述的每種消息類型都有一個類。

  對於C#, 編譯器為每個.proto文件生成一個.cs文件,文件中描述的每種消息類型都有一個類。

  通過所選語言的教程( proto 3版本即將推出),您可以了解關於為每種語言使用API的更多信息。有關更多的API細節,請參見相關的API參考( proto 3版本也即將推出)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM