1. 程式人生 > >protobuf語法

protobuf語法

本指南描述了怎樣使用protocol buffer 語法來構造你的protocol buffer資料,包括.proto檔案語法以及怎樣生成.proto檔案的資料訪問類。

定義一個訊息型別

先來看一個非常簡單的例子。假設你想定義一個“搜尋請求”的訊息格式,每一個請求含有一個查詢字串、你感興趣的查詢結果所在的頁數,以及每一頁多少條查詢結果。可以採用如下的方式來定義訊息型別的.proto檔案了:

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

SearchRequest訊息格式有3個欄位,在訊息中承載的資料分別對應於每一個欄位。其中每個欄位都有一個名字和一種型別。

指定欄位型別

在上面的例子中,所有欄位都是標量型別:兩個整型(page_number和result_per_page),一個string型別(query)。當然,你也可以為欄位指定其他的合成型別,包括列舉(enumerations)或其他訊息型別。

分配標識號

正如上述檔案格式,在訊息定義中,每個欄位都有唯一的一個數字識別符號。這些識別符號是用來在訊息的二進位制格式中識別各個欄位的,一旦開始使用就不能夠再改變。注:[1,15]之內的標識號在編碼的時候會佔用一個位元組。[16,2047]之內的標識號則佔用2個位元組。所以應該為那些頻繁出現的訊息元素保留 [1,15]之內的標識號。切記:要為將來有可能新增的、頻繁出現的標識號預留一些標識號。

最小的標識號可以從1開始,最大到2^29 - 1, or 536,870,911。不可以使用其中的[19000-19999]的標識號, Protobuf協議實現中對這些進行了預留。如果非要在.proto檔案中使用這些預留標識號,編譯時就會報警。

指定欄位規則

所指定的訊息欄位修飾符必須是如下之一:

  • required:一個格式良好的訊息一定要含有1個這種欄位。表示該值是必須要設定的;
  • optional:訊息格式中該欄位可以有0個或1個值(不超過1個)。
  • repeated:在一個格式良好的訊息中,這種欄位可以重複任意多次(包括0次)。重複的值的順序會被保留。表示該值可以重複,相當於java中的List。

由於一些歷史原因,基本數值型別的repeated的欄位並沒有被儘可能地高效編碼。在新的程式碼中,使用者應該使用特殊選項[packed=true]來保證更高效的編碼。如:

1repeated int32 samples = 4 [packed=true];

required是永久性的:在將一個欄位標識為required的時候,應該特別小心。如果在某些情況下不想寫入或者傳送一個required的欄位,將原始該欄位修飾符更改為optional可能會遇到問題——舊版本的使用者會認為不含該欄位的訊息是不完整的,從而可能會無目的的拒絕解析。在這種情況下,你應該考慮編寫特別針對於應用程式的、自定義的訊息校驗函式。Google的一些工程師得出了一個結論:使用required弊多於利;他們更 願意使用optional和repeated而不是required。當然,這個觀點並不具有普遍性。

新增更多訊息型別

在一個.proto檔案中可以定義多個訊息型別。在定義多個相關的訊息的時候,這一點特別有用——例如,如果想定義與SearchResponse訊息型別對應的回覆訊息格式的話,你可以將它新增到相同的.proto檔案中,如:

123456789message SearchRequest { required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3;}message SearchResponse { ...}

添加註釋

向.proto檔案添加註釋,可以使用C/C++/java風格的雙斜槓(//) 語法格式,如:

12345message SearchRequest { required string query = 1; optional int32 page_number = 2;// Which page number do we want? optional int32 result_per_page = 3;// Number of results to return per page.}

從.proto檔案生成了什麼?

當用protocolbuffer編譯器來執行.proto檔案時,編譯器將生成所選擇語言的程式碼,這些程式碼可以操作在.proto檔案中定義的訊息型別,包括獲取、設定欄位值,將訊息序列化到一個輸出流中,以及從一個輸入流中解析訊息。

  • 對C++來說,編譯器會為每個.proto檔案生成一個.h檔案和一個.cc檔案,.proto檔案中的每一個訊息有一個對應的類。
  • 對Java來說,編譯器為每一個訊息型別生成了一個.java檔案,以及一個特殊的Builder類(該類是用來建立訊息類介面的)。
  • 對Python來說,有點不太一樣——Python編譯器為.proto檔案中的每個訊息型別生成一個含有靜態描述符的模組,,該模組與一個元類(metaclass)在執行時(runtime)被用來建立所需的Python資料訪問類。

標量數值型別

一個標量訊息欄位可以含有一個如下的型別——該表格展示了定義於.proto檔案中的型別,以及與之對應的、在自動生成的訪問類中定義的型別:

.proto型別

Java 型別

C++型別

備註

double

double

double

float

float

float

int32

int

int32

使用可變長編碼方式。編碼負數時不夠高效——如果你的欄位可能含有負數,那麼請使用sint32。

int64

long

int64

使用可變長編碼方式。編碼負數時不夠高效——如果你的欄位可能含有負數,那麼請使用sint64。

uint32

int[1]

uint32

Uses variable-length encoding.

uint64

long[1]uint64Uses variable-length encoding.

sint32

int

int32

使用可變長編碼方式。有符號的整型值。編碼時比通常的int32高效。

sint64

long

int64

使用可變長編碼方式。有符號的整型值。編碼時比通常的int64高效。

fixed32

int[1]

uint32

總是4個位元組。如果數值總是比總是比228大的話,這個型別會比uint32高效。

fixed64

long[1]

uint64

總是8個位元組。如果數值總是比總是比256大的話,這個型別會比uint64高效。

sfixed32

int

int32

總是4個位元組。

sfixed64

long

int64

總是8個位元組。

bool

boolean

bool

string

String

string

一個字串必須是UTF-8編碼或者7-bit ASCII編碼的文字。

bytes

ByteString

string

可能包含任意順序的位元組資料。

Optional的欄位和預設值

如上所述,訊息描述中的一個元素可以被標記為“可選的”(optional)。一個格式良好的訊息可以包含0個或一個optional的元素。當解 析訊息時,如果它不包含optional的元素值,那麼解析出來的物件中的對應欄位就被置為預設值。預設值可以在訊息描述檔案中指定。例如,要為 SearchRequest訊息的result_per_page欄位指定預設值10,在定義訊息格式時如下所示:

1optional int32 result_per_page = 3 [default = 10];

如果沒有為optional的元素指定預設值,就會使用與特定型別相關的預設值:對string來說,預設值是空字串。對bool來說,預設值是false。對數值型別來說,預設值是0。對列舉來說,預設值是列舉型別定義中的第一個值。

列舉

當需要定義一個訊息型別的時候,可能想為一個欄位指定某“預定義值序列”中的一個值。例如,假設要為每一個SearchRequest訊息新增一個 corpus欄位,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一個。 其實可以很容易地實現這一點:通過向訊息定義中新增一個列舉(enum)就可以了。一個enum型別的欄位只能用指定的常量集中的一個值作為其值(如果嘗 試指定不同的值,解析器就會把它當作一個未知的欄位來對待)。在下面的例子中,在訊息格式中添加了一個叫做Corpus的列舉型別——它含有所有可能的值 ——以及一個型別為Corpus的欄位:

123456789101112131415

相關推薦

Protobuf 語法 - 史上最簡教程

Protobuf 語法簡明教程 瘋狂創客圈 死磕Netty 億級流量架構系列之12 【部落格園 總入口 】 在protobuf中,協議是由一系列的訊息組成的。因此最重要的就是定義通訊時使用到的訊息格式。 一個Protobuf 訊息(對應JAVA類),由至少一個欄位(對應Java類屬性)組合而成。

Protobuf 語法 | 史上最簡教程

Protobuf 語法簡明教程 瘋狂創客圈 死磕Netty 億級流量架構系列之12 【部落格園 總入口 】 在protobuf中,協議是由一系列的訊息組成的。因此最重要的就是定義通訊時使用到的訊息格式。 一個Protobuf 訊息(對應JAVA類),由至少一個欄位(對應Ja

Protobuf 語法指南

英文: Proto Buffers Language Guide 本指南描述了怎樣使用protocol buffer 語法來構造你的protocol buffer資料,包括.proto檔案語法以及怎樣生成.proto檔案的資料訪問類。(本文只針對proto2的語法) 本文是一個參考指南——如果要

Golang gRPC實踐 連載三 Protobuf語法

Protobuf語法 gRPC推薦使用proto3,本節只介紹常用語法,更多高階使用姿勢請參考官方文件 Message定義 一個message型別定義描述了一個請求或相應的訊息格式,可以包含多種型別欄位。例如定義一個搜尋請求的訊息格式,每個請求包含查詢字串、頁碼、

protobuf語法

本指南描述了怎樣使用protocol buffer 語法來構造你的protocol buffer資料,包括.proto檔案語法以及怎樣生成.proto檔案的資料訪問類。定義一個訊息型別先來看一個非常簡單的例子。假設你想定義一個“搜尋請求”的訊息格式,每一個請求含有一個查詢字串、你感興趣的查詢結果所在的頁數,以

Google_Protobuf協議——Protobuf語法

protobuf的語法圍繞著字尾為.proto的檔案進行構建。 語法協議規則:syntax 目前的語法協議規則最新支援proto3 在檔案描述為 yntax = "proto3"; 每個.proto檔案必須闡明支援的語法協議規則。 不同

Protobuf語言指南——.proto檔案語法詳解

Protobuf語言指南 l  定義一個訊息(message)型別 l  標量值型別 l  Optional 的欄位及預設值 l  列舉 l  使用其他訊息型別 l  巢狀型別 l  更新一個訊息型別 l  擴充套件 l  包(package) l 

Python基礎語法

python行 縮進 字典一、行和縮進 Python與其他語言最大的區別就是,Python的代碼塊不適用大括號{}來控制類,數以及其他邏輯判斷。python 最具特色的就是用縮進來寫模塊。 縮進的空白數量是可變的,但是所有代碼塊語言必選包含相同的縮進空白數量,這個必須嚴格執行。 如下所示:

AutoMapper新語法

ima ppp snap app profile eat orm per hot var mapper = config.CreateMapper();// orIMapper mapper = new Mapper(config);var dest = mapper.Ma

異常判斷語法

執行 pan 代碼 判斷 pre finall 異常 final 代碼塊 1 try: 2 ‘主邏輯代碼。框住了你感覺會拋出異常的代碼‘ 3 4 except: 5 ‘try代碼塊裏面如果拋出一場了,該執行這裏的內容‘ 6 7 else:

Markdown語法入門

his single 不能 data- ont 入門 -i easy 中間 大家在項目開發的過程中,編寫文檔是不是大家的痛點呢?如果文檔只是寫在word裏面,那不成問題。文檔格式在windows,Linux或者MacOS之間不兼容,那麽將word直接轉為PDF再發布出去,這

[SQL] SQL SERVER基礎語法

取消 implicit 全連接 樹結構 需要 強制 rom lec 多行 Struct Query Language 1.3NF   a.原子性   b.不能數據冗余   c.引用其他表的主鍵 2.約束   a.非空約束   b.主鍵約束   c.唯一約束   d.默認

[JS] javascript基礎語法

原因 方法 間接 war init err ring tag 是否 1.javascript是什麽   js是具有面向對象能力的,解釋性的程序設計語言. 2.js的類型   [基本類型]:string number boolean   [復合類型]:對象(對象,函數,數

[C#] CSharp 基本語法

windows library 命名方式 編譯器 帕斯卡 一、基礎1.規範:除常量外,所有變量用駝峰命名方式,其它用帕斯卡命名方式. 2.編譯:首先由csc.exe將cs文件編譯成MSIL.當雙擊exe的時候,會由clr的jit(just in time)編譯器再次編譯成cpu指令.csc

語法、語義與哲學

alt blog 都對 含義 技術 png logs tail 自然 語法:語言要素組成語句的規則;是部分如何和成整體的原則; 物質的組成規則。 語義:描述的是信息流通的過程;本質是信息的可理解性。 http://www.juweixin.com/t/detail/

Python-06:Python語法基礎-數與字符串

com -1 進行 距離 Coding 開始 mage gin spl 1、數的類型   Python中數的類型主要是有5中,分別有整數型(int)、長整型(long)、浮點型(float)、布爾型(bool)、復數型(complex)   例如: 0 -1 1 -9

Python-07:Python語法基礎-數據類型

數據類型 有序 索引 img utf http col 符號 數組 1、基本數據類型 2、列表   在Python中沒有數組!!!和數組類似的就是列表和元組了   列表就是存儲一連串元素的 容器。用[]來表示,是 有序排列的 3、元組   元組裏面的元素也是能進行

php基礎語法

弱類型 打印數組 類型 錯誤 比較 tty 同時 中文 大寫 js是前段腳本語言 php是後端腳本語言 一、所建的文件都要存在wap下的www裏面 二、所有的文件名都不能包含中文 三、通過輸入 localhost/www下的文件名稱,可以瀏覽 四、在DW內新建站點,更改站點

Protobuf使用規範分享

二進制 兼容性 生成器 程序 數據流 一、Protobuf 的優點  Protobuf 有如 XML,不過它更小、更快、也更簡單。它以高效的二進制方式存儲,比 XML 小 3 到 10 倍,快 20 到 100 倍。你可以定義自己的數據結構,然後使用代碼生成器生成的代碼來讀寫這個數據結構。

Mina、Netty、Twisted一起學(五):整合protobuf

ear ive obj con line 谷歌 encode etc 創建 protobuf是谷歌的Protocol Buffers的簡稱,用於結構化數據和字節碼之間互相轉換(序列化、反序列化),一般應用於網絡傳輸,可支持多種編程語言。protobuf怎樣使用這裏不再介紹