google protobuf_protobuf 指南

4bc3c3c58a64102533a90dd60156396a.png
  • 簡介
  • 安裝
  • 語言定義
    • 特殊指令
    • 定義服務
    • JSON 支持
    • 選項
    • 生成代碼
    • 基礎類型
    • 更新 message
  • Golang 下使用
  • 參考

簡介

Protocol Buffers 是 google 出品的一種數據交換格式, 縮寫為 protobuf.

主要介紹 proto3 版本和 Golang 下的使用.

安裝

protobuf 分為編譯器和運行時兩部分. 編譯器直接使用預編譯的二進制文件即可, 可以從 releases 上下載.

protobuf 運行時就是不同語言對應的庫, 以 Golang 為例:

go get github.com/golang/protobuf/protoc-gen-go

語言定義

protobuf 現在有兩個版本, proto2 和 proto3. 本著學新不學舊的原則, 這里只介紹 proto3.

既然是一種數據交換格式, 必然是要學習它的語法的, 就像學習 JSON 一樣, 你總得知道如何定義.

默認的文件是 .proto.

下面是一個簡單的例子, 來自于官方文檔.

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

首行定義了語法版本, 即使用 proto3 版本. 然后定義了一個名為 SearchRequest 的 message, 以及它包含的字段(鍵值對). message 的結構非常類似于各種語言中的 struct, dict 或者 map.

每個字段包括三個部分, 類型, 字段名和字段編號. 前兩個部分非常易懂, 主要解釋一下字段編號. 在同一個 message 中字段編號應該是唯一的, 用于在 message 的二進制格式(message binary format)中標識字段. 因此數字的大小決定了編碼的長度, 1-15 的數字只占用一個字節.

注釋語法是 ///* ... */.

特殊指令

使用 reserved 注明已被廢棄的字段編號和字段名稱.

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

使用 repeated 可以指定重復字段, 即數組.

message Test4 {repeated int32 d = 4 [packed=true];
}

使用 enum 定義枚舉類型. 每個枚舉定義都必須包含一個映射值為 0 的常量作為第一個元素.

message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;enum Corpus {UNIVERSAL = 0;WEB = 1;IMAGES = 2;LOCAL = 3;NEWS = 4;PRODUCTS = 5;VIDEO = 6;}Corpus corpus = 4;
}

定義枚舉時, 可以使用 allow_alias 選項允許枚舉值的別名.

enum EnumAllowingAlias {option allow_alias = true;UNKNOWN = 0;STARTED = 1;RUNNING = 1;  // RUNNING 是 STARTED 的別名
}

類型也可以嵌套使用.

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

使用 import 可以導入外部定義.

import "myproject/other_protos.proto";

使用 import public 可以傳遞導入依賴, 通常用于被導入的 proto 文件需要更改的情況下.

import public "new.proto";

protocol 編譯器搜索的位置是命令行參數中的 -I/--proto_path flag. 如果沒有提供, 則搜索編譯器被調用時所在的目錄.

Any 類型可以讓你可以在沒有它們的 proto 定義時, 將 messages 用作內嵌的類型. 一個 Any 包括任意的二進制序列化的 message, 就像 bytes 類型那樣, 以及用作該類型的全局唯一的標識符 URL.

import "google/protobuf/any.proto";message ErrorStatus {string message = 1;repeated google.protobuf.Any details = 2;
}

默認的類型 URL 是 type.googleapis.com/packagename.messagename.

如果你有一個 message 包括許多字段, 但同時最多只有一個字段會被設置, 可以使用 Oneof 特性來節省內存. Oneof 字段和普通的字段沒有區別, 除了所有這些 Oneof 字段共享內存, 且同時只能由一個字段被設置. 你可以使用特殊的 case()WhichOneof() 方法檢查哪個字段被設置了, 具體方法名稱取決于實現的語言.

message SampleMessage {oneof test_oneof {string name = 4;SubMessage sub_message = 9;}
}

可以在 Oneof 中添加任何類型的字段, 但不能使用 repeated.

使用 map 可以創建關聯映射.

map<key_type, value_type> map_field = N;
map<string, Project> projects = 3;

key_type 可以是 integral 或 string 類型, 即 scalar 類型中除了 floating point types 和 bytes 以外的類型. value_type 可以是除 map 以外的任何類型.

使用 package 可以設置命名空間, 防止 message 類型沖突.

package foo.bar;
message Open { ... }

在另一個 proto 文件中使用.

message Foo {...foo.bar.Open open = 1;...
}

package 說明符會影響不同語言生成代碼的方式:

  • Python: 忽略 package 指令
  • Golang: package 用作 Go 包名, 除了你使用 option go_package 顯式聲明包名

定義服務

如果你想要和 RPC 系統集成使用, 你可以定義 RPC 服務接口, 編譯器會根據選擇的語言, 生成對應的服務接口代碼和存根.

service SearchService {rpc Search (SearchRequest) returns (SearchResponse);
}

最常見的是和 gRPC 一起使用.

JSON 支持

proto3 支持 JSON 中的規范編碼, 具體的類型轉換關系, 查看官方文檔.

選項

有很多選項可以調節特性的行為, 完整的選項列表定義在 google/protobuf/descriptor.proto.

生成代碼

要生成代碼, 需要使用下面的命令, 對于 Golang 需要安裝額外的插件.

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto

基礎類型

標量值類型和各種語言間的轉換可以參考 官方文檔.

包括以下類型:

double
float
int32
int64
unit32
unit64
sint32  編碼負數比 int32 更高效
sint64
fixed32 固定四字節. 如果數字通常大于 2^28, 比 uint32 更高效
fixed64
sfixed32 負數優化版本的 fixed32
sfixed64
bool
string
bytes

更新 message

官方指南翻譯

  • 不要更改任何現有字段的字段編號.
  • 如果添加新的字段, 仍然可以使用新生成的代碼解析舊的 message 格式. 但應該自行處理新加字段的默認值. 使用新代碼創建的 message 也可以被舊代碼解析, 那些新字段會被忽略.
  • 字段可以被刪除, 只要不要復用那些字段編號. 要重命名字段, 可以給舊字段添加 OBSOLETE_ 前綴, 或者將字段編號設置為 reserved.
  • int32, uint32, int64, uint64, bool 是相互兼容的類型.
  • sint32 和 sint64 是相互兼容的, 但不兼容其他 int 類型.
  • string 和 bytes 可以是兼容的, 只要 bytes 是有效的 UTF-8.
  • 嵌入的 message 可以和 bytes 兼容, 如果 bytes 包含 message 的編碼后的版本.
  • fixed32 和 sfixed32 兼容, fixed64 和 sfixed64 兼容.
  • enum 在 wire 格式上兼容 int32, uint32, int64, uint64(如果值不合適會被截斷). 當 message 被反序列化時, 客戶端代碼可以用不同的方式對待它們. 比如, 未識別的 proto3 的 enum 類型將會保存在 message 中, 但它如何 表示是語言特定的. int 字段總是會保留它的值.
  • 將一個單個值更改為新 oneof 的成員是安全的且二進制兼容的. 移動多個字段到一個新的 oneof 可能是安全的, 如果你確保沒有 code 被多次設置. 移動任何字段到一個已存在的 oneof 是不安全的.

Golang 下使用

定義 protobuf 文件 hello.proto 的內容為:

syntax = "proto3";import "google/protobuf/any.proto";package hello;
option go_package = "hello";message HelloReq {string name = 1;
}message HelloResp {int32 code = 1;string greet = 2;google.protobuf.Any details = 3;
}service HelloService {rpc Greet(HelloReq) returns (HelloResp);
}

初始化項目, 并生成文件:

go mod init tzh.com/app
go get github.com/golang/protobuf/protoc-gen-go
mkdir hello
# 假設 protoc3 已經解壓好了
.protoc3binprotoc.exe  --proto_path=. --go_out=./hello hello.proto

main.go 如下:

package mainimport ("crypto/rand""fmt""github.com/golang/protobuf/proto""github.com/golang/protobuf/ptypes/any"hello "tzh.com/app/hello"
)func main() {req := &hello.HelloReq{Name: "hello",}details := make([]byte, 10)rand.Read(details)resp := &hello.HelloResp{Code:    1,Greet:   "hello name",Details: &any.Any{Value: details},}fmt.Println(req.String())fmt.Println(resp.String())// 序列化data, _ := proto.Marshal(req)fmt.Println(data)// 反序列化newReq := &hello.HelloReq{}proto.Unmarshal(data, newReq)fmt.Println(newReq)fmt.Println("text format", proto.MarshalTextString(req))}

如果你去看生成的代碼, 會發現沒有 HelloService 相關的內容, 這是因為沒有使用 gRPC.

參考

  • github
  • go protobuf
  • proto3
  • Go Generated Code

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532142.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532142.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532142.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機無法裝補丁,電腦無法安裝kb4012212補丁如何處理|電腦無法安裝kb4012212補丁的處理方法...

最近&#xff0c;不少用戶的電腦都被《永恒之藍》病毒侵襲&#xff0c;因此微軟官方推出了預防補丁 — kb4012212&#xff0c;正常系統只要安裝該補丁就能避免電腦遭到傷害。不過&#xff0c;有用戶反饋自己遇到了電腦無法安裝kb4012212補丁的情況&#xff0c;該怎么辦呢&#…

shell181網格劃分_ANSYS中SHELL181單元理解和參數詳解?-

頂部和底部的平均值不合適的時候&#xff0c;你應該用這個選項來得到正確的中見面的結果(薄膜結果);例子中包含黑線性材料特性的中間面應力、應變 &#xff0c;以及在包含諸如譜分析等測長操作的模態疊加之后的中間面結果。 KEYOPT(9) 1 用來從用戶子程序中讀取初始厚度數據。…

使用計算機繪制景物圖像的兩個主要步驟是,計算機11考試.doc

文檔介紹&#xff1a;第五章[4]. 一張CD盤片上存儲的立體聲高保真全頻帶數字音樂約可播放一小時,則其數據量大約是______。A、800MBB、635MBC、400MBD、1GB[6]. 衛星數字電視和新一代數字視盤DVD采用______作為數字視頻壓縮標準。MPEG-2 | MPEG2[10]. 聲卡在計算機中用于完成聲…

mysql在哪里寫代碼_[譯] 如何寫好 Go 代碼

原文&#xff1a;https://scene-si.org/2018/07/24/writing-great-go-code/我寫了多年的 Go 微服務&#xff0c;并在寫完兩本關于 (API Foundations in Go 和 12 Factor Applications with Docker and Go) 主題的書之后&#xff0c;有了一些關于如何寫好 Go 代碼的想法但首先&a…

學畫畫軟件app推薦_路由器管理軟件哪個好?6款路由器管理APP推薦_軟件評測

無限網絡應用越來越廣泛&#xff0c;由此應運而生了許多可以蹭網的軟件&#xff0c;家里的網速突然變慢了&#xff0c;也許就是隔壁的小哥哥小姐姐在蹭網絡&#xff0c;那么如何避免被蹭網&#xff1f;今天小編給各位小伙伴推薦幾款路由器管理軟件&#xff0c;發現網絡變慢了&a…

408計算機考研 各科題目題號,2021考研408計算機專業基礎綜合數據結構試題特點分析...

2021考研408計算機專業基礎綜合數據結構試題特點分析2021考研初試結束后&#xff0c;新東方在線考研網為各位考研考生梳理"2021考研408計算機專業基礎綜合數據結構試題特點分析"內容&#xff0c;同時新東方在線考研各研究院院長針對2021考研各科目試題變化及難度進行…

各個圖標的意思_冬奧體育圖標設計團隊負責人林存真:每一個圖標要畫100稿以上...

林存真中央美術學院設計學院副院長、北京冬奧組委文化活動部形象景觀藝術總監、北京冬奧會體育圖標設計團隊負責人。12月31日晚&#xff0c;北京2022年冬奧會和冬殘奧會體育圖標正式發布。在體育圖標發布前夕&#xff0c;新京報記者采訪了北京冬奧會體育圖標設計團隊的負責人&a…

delphi制作上下開幕效果_2019中超聯賽揭幕戰在深圳舉行 現場開幕式亮點多多

3月2日晚&#xff0c;2019中超聯賽開幕式在深圳大運中心體育場舉行。隨著中國足協黨委書記杜兆才正式宣布2019年中超聯賽開幕&#xff0c;以“超精彩”為口號的2019新賽季中超聯賽正式打響。本賽季中超聯賽是出臺“注資帽”、“薪酬帽”、“獎金帽”、“轉會帽”之后的第一個賽…

ae正在發生崩潰_AE錯誤:正在發生崩潰的解決方法,原創問題解決方案

AE在使用過程中,可能會出現一些問題。有的問題是莫名其妙出現。例如剛剛還在正常使用AE軟件,下一次再打開的時候就會出現問題。今天給大家說的是如何去解決after effects錯誤:正在發生崩潰這個問題 。該問題所提供的解決方法為實際操作過,并成功解決。所以才寫出來給大家提…

計算機二級公共,計算機二級公共基礎知識

計算機二級公共基礎知識計算機二級考試包括計算機基礎知識。雖然分值不高但是我們還是要把握好每一分。下面百分網小編整理了相關計算機二級公共基礎知識&#xff0c;希望大家喜歡。計算機二級公共基礎知識1.1棧和隊列1、棧及其基本運算棧是限定在一端進行插入與刪除運算的線性…

echarts map 點擊地圖區域變色_繪制炫酷的地圖,不只是pyecharts.map!

導讀&#xff1a;地圖可視化是一種非常直觀的數據分析結果展現形式&#xff0c;python有很多可視化庫可以實現&#xff0c;pyecharts就是很多python愛好者喜愛的實現地圖可視化方法之一。不可否認&#xff0c;pyecharts繪制的地圖實現方便、圖形美觀而且支持交互&#xff0c;但…

金蝶kis專業版公網訪問_金蝶KIS云專業版—【賬務處理】進階操作101問

對KIS專業版【賬務處理】模塊日常操作之外的各種問題進行回答&#xff0c;幫助老師們快速進階此模塊的操作&#xff0c;提高軟件的便利性。1.專業版資產負債表如何移動表頁位置&#xff1f;【操作步驟】 1、單擊【報表與分析】-【資產負債表】&#xff1b;2、單擊左上角菜單欄【…

奧鵬東師計算機應用基礎18,免費在線作業答案奧鵬東師計算機應用基礎15秋在線作業1試卷及答案(1)...

奧鵬東師計算機應用基礎15秋在線作業1試卷及答案(1)一、單選題(共25道試題&#xff0c;共62.5分。)1.在Excel 中保存的工作簿默認的文件擴展名是()。A. XLSB. DOCC. DBFD. TXT正確答案&#xff1a;A2.中文Windows 2000的“桌面”是指()。A. 整個屏幕B. 某個窗口2015奧鵬作業答案…

es集群搭建_滴滴Elasticsearch 集群跨版本升級與平臺重構之路

前不久&#xff0c;滴滴ES團隊將維護的30多個ES集群&#xff0c;3500多個ES節點&#xff0c;8PB的數據&#xff0c;從2.3.3跨大版本無縫升級到6.6.1。在對用戶查詢寫入基本零影響和改動的前提下&#xff0c;解決了ES跨大版本協議不兼容、文件格式不兼容、mapping不兼容等難題&a…

電子工程可以報考二建_非工程類專業也能報考二建嗎?

非工程類專業也能報考二建嗎&#xff1f;2020年非工程類專業能考二級建造師的省份匯總整理&#xff01;2020年二級建造師考試報名公告陸續公布中&#xff0c;目前江西、陜西、江蘇三省公布了報名時間&#xff0c;其他省份報名時間暫時未確定。四川省已經受疫情影響推遲五月的考…

計算機考試中英文打字題,計算機信息技術(五筆及中英文打字測試試題)

計算機信息技術(五筆及中英文打字測試試題) (14頁)本資源提供全文預覽&#xff0c;點擊全文預覽即可全文預覽,如果喜歡文檔就下載吧&#xff0c;查找使用更方便哦&#xff01;14.9 積分第一章基本知識習題答案一、填空題1. 計算機信息高新技術考試劃分為五、四、三、二、_ 5個等…

pil python 安裝_20行Python代碼給微信頭像戴帽子

作者 | Leauky&#xff0c;北理工碩士在讀&#xff0c;非CS專業的Python愛好者。朋友圈里微信官方要求戴圣誕帽的活動曾經火爆一時&#xff0c;有些會玩的小伙伴都悄咪咪地用美圖秀秀一類的 app 給自己頭像 p 一頂&#xff0c;然后可高興地表示“哎呀好神奇hhhh”&#xff0c;呆…

arcgis 屬性表 匯總_Arcgis中遙感影像地理配準、矢量化與地圖制作

目的&#xff1a;將遙感圖像進行地理配準、矢量化&#xff0c;并且制作地圖。要求&#xff1a;對的遙感圖像進行地理配準&#xff1b;矢量化建筑物、綠地、道路、水體等主要地物要素&#xff1b;對各類地物要素進行符號化設置并對其名稱進行標注&#xff1b;添加指北針、比例尺…

怎么查看計算機的系統內存大小,Windows10系統怎么查看電腦內存大小

很多用戶在升級到windows10系統之后&#xff0c;因為很多界面和操作都跟之前的Windows系統不一樣&#xff0c;所以很多操作都不知道要如何下手&#xff0c;比如想要查看電腦內存大小的時候卻不知道要怎么操作&#xff0c;其實方法很簡單&#xff0c;下面給大家介紹一下Windows1…

java類初始化順序_《To Be a Better Javaer》-- Java 基礎篇 vol.2:面向對象

Java是面向對象的高級編程語言&#xff0c;面向對象的特征如下&#xff1a;面向對象具有抽象、封裝、繼承、多態等特性&#xff1b;面向對象可以將復雜的業務邏輯簡單化&#xff0c;增強代碼復用性&#xff1b;面向對象是一種常見的思想&#xff0c;比較符合人們的思考習慣。面…