最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go protobuf?詳解

 更新時間:2024年01月04日 10:35:42   作者:野生的狒狒  
Protobuf是Protocol Buffers的簡稱,它是Google公司開發(fā)的一種數(shù)據(jù)描述語言,是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化,這篇文章主要介紹了protobuf?詳解,需要的朋友可以參考下

protobuf簡介

Protobuf是Protocol Buffers的簡稱,它是Google公司開發(fā)的一種數(shù)據(jù)描述語言,是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化 。它很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式。可用于通訊協(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。目前提供了 C++、Java、Python 三種語言的 API。

  • protobuf是類似與json一樣的數(shù)據(jù)描述語言(數(shù)據(jù)格式)
  • protobuf非常適合于RPC數(shù)據(jù)交換格式

注意:protobuf本身并不是和gRPC綁定的。它也可以被用于非RPC場景,如存儲等

protobuf的優(yōu)劣勢

1)優(yōu)勢:

  • 序列化后體積相比Json和XML很小,適合網(wǎng)絡(luò)傳輸
  • 序列化反序列化速度很快,快于Json的處理速度
  • 消息格式升級和兼容性還不錯
  • 支持跨平臺多語言

2)劣勢:

  • 應(yīng)用不夠廣(相比xml和json)
  • 二進(jìn)制格式導(dǎo)致可讀性差
  • 缺乏自描述

protoc安裝(windows)

protoc就是protobuf的編譯器,它把proto文件編譯成不同的語言

下載安裝protoc編譯器(protoc)

下載protobuf:https://github.com/protocolbuffers/protobuf/releases/download/v3.20.1/protoc-3.20.1-win64.zip

解壓后,將目錄中的 bin 目錄的路徑添加到系統(tǒng)環(huán)境變量,然后打開cmd輸入protoc查看輸出信息,此時則安裝成功

安裝protocbuf的go插件(protoc-gen-go)

由于protobuf并沒直接支持go語言需要我們手動安裝相關(guān)插件

protocol buffer編譯器需要一個插件來根據(jù)提供的proto文件生成 Go 代碼,Go1.16+要使用下面的命令安裝插件:

 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest  // 目前最新版是v1.3.0

安裝grpc(grpc)

 go get -u -v google.golang.org/grpc@latest    // 目前最新版是v1.53.0

安裝grpc的go插件(protoc-gen-go-grpc)

說明:在google.golang.org/protobuf中,protoc-gen-go純粹用來生成pb序列化相關(guān)的文件,不再承載gRPC代碼生成功能,所以如果要生成grpc相關(guān)的代碼需要安裝grpc-go相關(guān)的插件:protoc-gen-go-grpc

 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest  // 目前最新版是v1.3.0

protobuf語法

protobuf語法

類型:類型不僅可以是標(biāo)量類型(intstring等),也可以是復(fù)合類型(enum等),也可以是其他message

字段名:字段名比較推薦的是使用下劃線/分隔名稱

字段編號:一個message內(nèi)每一個字段編號都必須唯一的,在編碼后其實傳遞的是這個編號而不是字段名

字段規(guī)則:消息字段可以是以下字段之一

singular:格式正確的消息可以有零個或一個字段(但不能超過一個)。使用 proto3 語法時,如果未為給定字段指定其他字段規(guī)則,則這是默認(rèn)字段規(guī)則

optional:與 singular 相同,不過可以檢查該值是否明確設(shè)置

repeated:在格式正確的消息中,此字段類型可以重復(fù)零次或多次。系統(tǒng)會保留重復(fù)值的順序

map:這是一個成對的鍵值對字段

保留字段:為了避免再次使用到已移除的字段可以設(shè)定保留字段。如果任何未來用戶嘗試使用這些字段標(biāo)識符,編譯器就會報錯

簡單語法

proto文件基本語法

 syntax = "proto3";              // 指定版本信息,不指定會報錯
 package pb;                     // 后期生成go文件的包名
 // message為關(guān)鍵字,作用為定義一種消息類型
 message Person{
     string name = 1;   // 名字
     int32  age = 2 ;   // 年齡
 }
 ?
 enum test{
     int32 age = 0;
 }

protobuf消息的定義(或者稱為描述)通常都寫在一個以 .proto 結(jié)尾的文件中:

  • 第一行指定正在使用proto3語法:如果不這樣做,協(xié)議緩沖區(qū)編譯器將假定正在使用proto2(這也必須是文件的第一個非空的非注釋行)
  • 第二行package指明當(dāng)前是pb包(生成go文件之后和Go的包名保持一致)
  • message關(guān)鍵字定義一個Person消息體,類似于go語言中的結(jié)構(gòu)體,是包含一系列類型數(shù)據(jù)的集合。
    • 許多標(biāo)準(zhǔn)的簡單數(shù)據(jù)類型都可以作為字段類型,包括bool,int32, float,double,和string
    • 也可以使用其他message類型作為字段類型。

在message中有一個字符串類型的value成員,該成員編碼時用1代替名字。在json中是通過成員的名字來綁定對應(yīng)的數(shù)據(jù),但是Protobuf編碼卻是通過成員的唯一編號來綁定對應(yīng)的數(shù)據(jù),因此Protobuf編碼后數(shù)據(jù)的體積會比較小,能夠快速傳輸,缺點是不利于閱讀。

message常見的數(shù)據(jù)類型與go中類型對比

.proto類型Go類型介紹
doublefloat6464位浮點數(shù)
floatfloat3232位浮點數(shù)
int32int32使用可變長度編碼。編碼負(fù)數(shù)效率低下——如果你的字段可能有負(fù)值,請改用sint32。
int64int64使用可變長度編碼。編碼負(fù)數(shù)效率低下——如果你的字段可能有負(fù)值,請改用sint64。
uint32uint32使用可變長度編碼。
uint64uint64使用可變長度編碼。
sint32int32使用可變長度編碼。符號整型值。這些比常規(guī)int32s編碼負(fù)數(shù)更有效。
sint64int64使用可變長度編碼。符號整型值。這些比常規(guī)int64s編碼負(fù)數(shù)更有效。
fixed32uint32總是四字節(jié)。如果值通常大于228,則比uint 32更有效
fixed64uint64總是八字節(jié)。如果值通常大于256,則比uint64更有效
sfixed32int32總是四字節(jié)。
sfixed64int64總是八字節(jié)。
boolbool布爾類型
stringstring字符串必須始終包含UTF - 8編碼或7位ASCII文本
bytes[]byte可以包含任意字節(jié)序列

protobuff語法進(jìn)階

message嵌套

messsage除了能放簡單數(shù)據(jù)類型外,還能存放另外的message類型:

syntax = "proto3";          // 指定版本信息,不指定會報錯
 package pb;                 // 后期生成go文件的包名
 // message為關(guān)鍵字,作用為定義一種消息類型
 message Person{
     string name = 1;  // 名字
     int32  age = 2 ;  // 年齡
     // 定義一個message
     message PhoneNumber {
         string number = 1;
         int64 type = 2;
     }
     PhoneNumber phone = 3;
 }

message成員編號,可以不從1開始,但是不能重復(fù),不能使用19000 - 19999

repeated關(guān)鍵字

repeadted關(guān)鍵字類似與go中的切片,編譯之后對應(yīng)的也是go的切片,用法如下:

 syntax = "proto3";              // 指定版本信息,不指定會報錯
 package pb;                     // 后期生成go文件的包名
 // message為關(guān)鍵字,作用為定義一種消息類型
 message Person{
     string name = 1;   // 名字
     int32  age = 2 ;   // 年齡
     // 定義一個message
     message PhoneNumber {
         string number = 1;
         int64 type = 2;
     }
     repeated PhoneNumber phone = 3;
 }

默認(rèn)值

解析數(shù)據(jù)時,如果編碼的消息不包含特定的單數(shù)元素,則解析對象對象中的相應(yīng)字段將設(shè)置為該字段的默認(rèn)值

不同類型的默認(rèn)值不同,具體如下:

  • 對于字符串,默認(rèn)值為空字符串
  • 對于字節(jié),默認(rèn)值為空字節(jié)
  • 對于bools,默認(rèn)值為false
  • 對于數(shù)字類型,默認(rèn)值為零
  • 對于枚舉,默認(rèn)值是第一個定義的枚舉值,該值必須為0。
  • repeated字段默認(rèn)值是空列表
  • message字段的默認(rèn)值為空對象

enum關(guān)鍵字

在定義消息類型時,可能會希望其中一個字段有一個預(yù)定義的值列表

比如說,電話號碼字段有個類型,這個類型可以是,home,work,mobile

我們可以通過enum在消息定義中添加每個可能值的常量來非常簡單的執(zhí)行此操作。示例如下:

syntax = "proto3";              // 指定版本信息,不指定會報錯
 package pb;                     // 后期生成go文件的包名
 // message為關(guān)鍵字,作用為定義一種消息類型
 message Person{
     string name = 1;   // 名字
     int32  age = 2 ;   // 年齡
     // 定義一個message
     message PhoneNumber {
         string number = 1;
         PhoneType type = 2;
     }
     repeated PhoneNumber phone = 3;
 }
 ?
 // enum為關(guān)鍵字,作用為定義一種枚舉類型
 enum PhoneType {
     MOBILE = 0;
     HOME = 1;
     WORK = 2;
 }

如上,enum的第一個常量映射為0,每個枚舉定義必須包含一個映射到零的常量作為其第一個元素。這是因為:

必須有一個零值,以便我們可以使用0作為數(shù)字默認(rèn)值。

零值必須是第一個元素,以便與proto2語義兼容,其中第一個枚舉值始終是默認(rèn)值。

enum還可以為不同的枚舉常量指定相同的值來定義別名。如果想要使用這個功能必須將allow_alias選項設(shè)置為true,負(fù)責(zé)編譯器將報錯。示例如下:

syntax = "proto3";              // 指定版本信息,不指定會報錯
 package pb;                     // 后期生成go文件的包名
 // message為關(guān)鍵字,作用為定義一種消息類型
 message Person{
     string name = 1;   // 名字
     int32  age = 2 ;   // 年齡
     // 定義一個message
     message PhoneNumber {
         string number = 1;
         PhoneType type = 2;
     }
     repeated PhoneNumber phone = 3;
 }
 ?
 // enum為關(guān)鍵字,作用為定義一種枚舉類型
 enum PhoneType {
     // 如果不設(shè)置將報錯
     option allow_alias = true;
     MOBILE = 0;
     HOME = 1;
     WORK = 2;
     Personal = 2;
 }

oneof關(guān)鍵字

如果有一個包含許多字段的消息,并且最多只能同時設(shè)置其中的一個字段,則可以使用oneof功能,示例如下:

 message Person{
     string name = 1; // 名字
     int32  age = 2 ; // 年齡
     //定義一個message
     message PhoneNumber {
         string number = 1;
         PhoneType type = 2;
     }
 ?
     repeated PhoneNumber phone = 3;
     oneof data{
         string school = 5;
         int32 score = 6;
     }
 }

定義RPC服務(wù)

如果需要將message與RPC一起使用,則可以在.proto文件中定義RPC服務(wù)接口,protobuf編譯器將根據(jù)你選擇的語言生成RPC接口代碼。示例如下:

//定義RPC服務(wù)
 service HelloService {
     rpc Hello (Person)returns (Person);
 }

注意:默認(rèn)protobuf編譯期間,不編譯服務(wù),如果要想讓其編譯,需要使用gRPC

protobuf編譯

編譯器調(diào)用

protobuf 編譯是通過編譯器 protoc 進(jìn)行的,通過這個編譯器,我們可以把 .proto 文件生成 go,Java,Python,C++, Ruby或者C# 代碼

可以使用以下命令來通過 .proto 文件生成go代碼(以及grpc代碼)

// 將當(dāng)前目錄中的所有 .proto文件進(jìn)行編譯生成go代碼
 protoc --go_out=./ --go_opt=paths=source_relative *.proto

protobuf 編譯器會把 .proto 文件編譯成 .pd.go 文件

--go_out 參數(shù)

作用:指定go代碼生成的基本路徑

  • protocol buffer編譯器會將生成的Go代碼輸出到命令行參數(shù)go_out指定的位置
  • go_out標(biāo)志的參數(shù)是你希望編譯器編寫 Go 輸出的目錄
  • 編譯器會為每個.proto 文件輸入創(chuàng)建一個源文件
  • 輸出文件的名稱是通過將.proto 擴(kuò)展名替換為.pb.go 而創(chuàng)建的

--go_opt 參數(shù)

protoc-gen-go提供了--go_opt參數(shù)來為其指定參數(shù),可以設(shè)置多個:

paths=import:生成的文件會按go_package路徑來生成,當(dāng)然是在--go_out目錄

例如,go_out/$go_package/pb_filename.pb.go

如果未指定路徑標(biāo)志,這就是默認(rèn)輸出模式

paths=source_relative:輸出文件與輸入文件放在相同的目錄中

例如,一個protos/buzz.proto輸入文件會產(chǎn)生一個位于protos/buzz.pb.go的輸出文件。

module=$PREFIX:輸出文件放在以 Go 包的導(dǎo)入路徑命名的目錄中,但是從輸出文件名中刪除了指定的目錄前綴。

例如,輸入文件 pros/buzz.proto,其導(dǎo)入路徑為 example.com/project/protos/fizz 并指定example.com/projectmodule前綴,結(jié)果會產(chǎn)生一個名為 pros/fizz/buzz.pb.go 的輸出文件。

在module路徑之外生成任何 Go 包都會導(dǎo)致錯誤,此模式對于將生成的文件直接輸出到 Go 模塊非常有用。

--proto_path 參數(shù)

--proto_path=IMPORT_PATH

  • IMPORT_PATH是 .proto 文件所在的路徑,如果忽略則默認(rèn)當(dāng)前目錄。
  • 如果有多個目錄則可以多次調(diào)用--proto_path,它們將會順序的被訪問并執(zhí)行導(dǎo)入。

使用示例:

protoc --proto_path=src --go_out=out --go_opt=paths=source_relative foo.proto bar/baz.proto
 // 編譯器將從 `src` 目錄中讀取輸入文件 `foo.proto` 和 `bar/baz.proto`,并將輸出文件 `foo.pb.go` 和 `bar/baz.pb.go` 寫入 `out` 目錄。如果需要,編譯器會自動創(chuàng)建嵌套的輸出子目錄,但不會創(chuàng)建輸出目錄本身

使用grpc的go插件 安裝proto-gen-go-grpc

google.golang.org/protobuf中,protoc-gen-go純粹用來生成pb序列化相關(guān)的文件,不再承載gRPC代碼生成功能。生成gRPC相關(guān)代碼需要安裝grpc-go相關(guān)的插件protoc-gen-go-grpc

// 安裝protoc-gen-go-grpc
 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest  // 目前最新版是v1.3.0

生成grpc的go代碼:

// 主要是--go_grpc_out參數(shù)會生成go代碼
 protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative  *.proto

--go-grpc_out 參數(shù)

作用:指定grpc go代碼生成的基本路徑

命令會產(chǎn)生的go文件:

  • protoc-gen-go:包含所有類型的序列化和反序列化的go代碼
  • protoc-gen-go-grpc:包含service中的用來給client調(diào)用的接口定義以及service中的用來給服務(wù)端實現(xiàn)的接口定義

--go-grpc_opt 參數(shù)

protoc-gen-go類似,protoc-gen-go-grpc提供 --go-grpc_opt 來指定參數(shù),并可以設(shè)置多個

github.com/golang/protobuf 和 google.golang.org/protobuf github.com/golang/protobuf

  • github.com/golang/protobuf 現(xiàn)在已經(jīng)廢棄
  • 它可以同時生成pb和gRPC相關(guān)代碼的

用法:

// 它在--go_out加了plugin關(guān)鍵字,paths參數(shù)有兩個選項,分別是 import 和 source_relative
 --go_out=plugins=grpc,paths=import:.  *.proto

google.golang.org/protobuf

  • github.com/golang/protobuf的升級版本,v1.4.0之后github.com/golang/protobuf僅是google.golang.org/protobuf的包裝
  • 它純粹用來生成pb序列化相關(guān)的文件,不再承載gRPC代碼生成功能,生成gRPC相關(guān)代碼需要安裝grpc-go相關(guān)的插件protoc-gen-go-grpc

用法:

// 它額外添加了參數(shù)--go-grpc_out以調(diào)用protoc-gen-go-grpc插件生成grpc代碼
 protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relativ

到此這篇關(guān)于protobuf 詳解的文章就介紹到這了,更多相關(guān)protobuf 詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Golang中的各種時間操作

    詳解Golang中的各種時間操作

    這篇文章主要介紹了詳解Golang中的各種時間操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Golang中的錯誤處理深入分析

    Golang中的錯誤處理深入分析

    Go錯誤處理類似C語言,沒有提供任何異常,以及類java語言使用的try/catch異常處理機(jī)制。Go異常處理僅簡化為預(yù)定義的Error類型,Go沒有提供異常處理機(jī)制,不能拋出類似許多其他語言的異常。相反,Golang集成了新的錯誤處理機(jī)制,如panic和recovery
    2023-01-01
  • Go語言中GORM存取數(shù)組/自定義類型數(shù)據(jù)

    Go語言中GORM存取數(shù)組/自定義類型數(shù)據(jù)

    在使用gorm時往往默認(rèn)的數(shù)據(jù)類型不滿足我們的要求,需要使用一些自定義數(shù)據(jù)類型作為字段類型,下面這篇文章主要給大家介紹了關(guān)于Go語言中GORM存取數(shù)組/自定義類型數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Go Java算法之單詞規(guī)律示例詳解

    Go Java算法之單詞規(guī)律示例詳解

    這篇文章主要為大家介紹了Go Java算法之單詞規(guī)律示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang進(jìn)程內(nèi)存控制避免docker內(nèi)oom

    golang進(jìn)程內(nèi)存控制避免docker內(nèi)oom

    這篇文章主要為大家介紹了golang進(jìn)程內(nèi)存控制避免docker內(nèi)oom示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • go使用golangci-lint實現(xiàn)自動化代碼檢查

    go使用golangci-lint實現(xiàn)自動化代碼檢查

    golangci-lint的自動化代碼檢查方案,幫助開發(fā)者在開發(fā)過程中及時發(fā)現(xiàn)并修復(fù)代碼問題,本文將詳細(xì)介紹使用golangci-lint實現(xiàn)自動化代碼檢查,具有一定的參考價值,感興趣的可以了解一下
    2026-04-04
  • golang實現(xiàn)命令行程序的使用幫助功能

    golang實現(xiàn)命令行程序的使用幫助功能

    這篇文章介紹了golang實現(xiàn)命令行程序使用幫助的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Go語言學(xué)習(xí)技巧之命名規(guī)范

    Go語言學(xué)習(xí)技巧之命名規(guī)范

    最近在學(xué)習(xí)go語言,發(fā)現(xiàn)了不少需要整理的知識點,所以整理下分享出來,下面這篇文章主要給大家介紹了關(guān)于Go語言學(xué)習(xí)技巧之命名規(guī)范的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-12-12
  • go語言中字符串嵌套的幾種實現(xiàn)方式

    go語言中字符串嵌套的幾種實現(xiàn)方式

    在Go語言中,字符串嵌套可以通過多種方式實現(xiàn),包括使用雙引號和轉(zhuǎn)義字符、反引號、字符串拼接和格式化字符串,下面就來介紹一下,感興趣的可以了解一下
    2025-03-03
  • Go學(xué)習(xí)筆記之Zap日志的使用

    Go學(xué)習(xí)筆記之Zap日志的使用

    這篇文章主要為大家詳細(xì)介紹了Go語言中Zap日志的使用以及安裝,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下
    2022-07-07

最新評論

澄城县| 晋江市| 牟定县| 临夏市| 神农架林区| 枣阳市| 岑巩县| 金昌市| 岳西县| 镇平县| 漳平市| 泰和县| 赞皇县| 牟定县| 古田县| 沭阳县| 玉树县| 宁强县| 班玛县| 红安县| 和龙市| 潢川县| 鹤壁市| 睢宁县| 刚察县| 雅江县| 汉寿县| 满城县| 昭觉县| 柏乡县| 宁陵县| 康马县| 武陟县| 绵阳市| 乌兰县| 北宁市| 密山市| 内乡县| 鹤山市| 股票| 枝江市|