Golang Protocol Buffer案例詳解
Golang Protocol Buffer教程
本文介紹如何在Go應(yīng)用中利用Protocol Buffer數(shù)據(jù)格式。主要包括什么是Protocol Buffer數(shù)據(jù)格式,其超越傳統(tǒng)數(shù)據(jù)格式XML或JSON的優(yōu)勢(shì)是什么。
1. Protocol Buffer數(shù)據(jù)格式
Protocol Buffer,本質(zhì)就是一種數(shù)據(jù)格式,和JSON或XML一樣,不同的語言用于結(jié)構(gòu)化數(shù)據(jù)序列化或反序列化。該數(shù)據(jù)格式的優(yōu)勢(shì)是較xml或json更小,源于Google。假如我們有一個(gè)對(duì)象,我們用三種數(shù)據(jù)結(jié)構(gòu)進(jìn)行表示:
<person> <name>Elliot</name> <age>24</age> </person>
使用json表示占用空間更小:
{ "name": "Elliot", "age": 24 }
如果使用protocol buffer格式表示:
[10 6 69 108 108 105 111 116 16 24]
如果您仔細(xì)觀察上面編碼可能會(huì)看到,從數(shù)組位置2開始名字elliot被拼出來,e = 69, l = 108等等。后面是年齡的字節(jié)表示,24歲。
不過編碼格式內(nèi)容比我們看到的要多,下面會(huì)更詳細(xì)地解釋,如果您愿意可看其官方文檔。
現(xiàn)在這個(gè)示例數(shù)據(jù),Json和 Protocol Buffer格式幾乎沒有太大差別,但當(dāng)遇到數(shù)據(jù)量很大場景時(shí),差別就體現(xiàn)出來了。
2. 簡單示例
首先下載必要的依賴:
go get github.com/golang/protobuf go get github.com/golang/protobuf/proto
下載完成后,確保能夠在命令行中可以運(yùn)行 protoc 命令。下面我們定義 protobuf 結(jié)構(gòu),這里定義上面用來對(duì)比不同數(shù)據(jù)格式之間差異的person 對(duì)象。
首先指定我們使用的語法格式,這里使用 proto3,然后指定存放的包名。最后定義對(duì)象,Peson類型的消息及其包括的字段 name 和 age。
person.proto結(jié)構(gòu)定義如下:
syntax="proto3"; package main; message Person { string name = 1; int32 age = 2; }
然后在該文件的路徑下運(yùn)行下面命令:
protoc --go_out=. *.proto
即在當(dāng)前目錄下 生成所有擴(kuò)展名為 proto文件的 .pb.go 文件。
現(xiàn)在我們定義Person類型對(duì)象使用 protobuf格式進(jìn)行序列化。代碼如下;
import ( "fmt" "log" "github.com/golang/protobuf/proto" ) func main() { elliot := &Person{ Name: "Elliot", Age: 24, } data, err := proto.Marshal(elliot) if err != nil { log.Fatal("marshaling error: ", err) } // 打印原始的protobuf序列化對(duì)象 fmt.Println(data) // 反序列化進(jìn)行驗(yàn)證 newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // 打印 `newElliot` 對(duì)象進(jìn)行驗(yàn)證 fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.GetName()) }
使用go run 命令運(yùn)行,需要在main.go 后面?zhèn)魅?person.pb.go,命令如下:
go run main.go test.pb.go
在ide環(huán)境中可以直接運(yùn)行。輸出結(jié)果如下:
[10 6 69 108 108 105 111 116 16 24] name:"Elliot" age:24
3. 嵌套示例
我們已經(jīng)完成了一個(gè)非常簡單的示例,但現(xiàn)實(shí)中消息格式通常會(huì)遇到多個(gè)嵌套字段,下面增加嵌套類型字段。
我們?nèi)匀皇褂们懊?Person 類型,僅增加社交網(wǎng)絡(luò)的粉絲字段。SocialFollowers的消息類型如下:
syntax="proto3"; package main; message SocialFollowers { int32 youtube = 1; int32 twitter = 2; } message Person { string name = 1; int32 age = 2; SocialFollowers socialFollowers = 3; }
因?yàn)镻erson 類型已經(jīng)被修改了,需要重新運(yùn)行 protoc 命令:
protoc --go_out=. *.proto
現(xiàn)在同時(shí)修改代碼進(jìn)行測試,填充 elliot 對(duì)象使用 SocialFollowers 類型對(duì)象:
package main import ( "fmt" "log" "github.com/golang/protobuf/proto" ) func main() { elliot := Person{ Name: "Elliot", Age: 24, SocialFollowers: &SocialFollowers{ Youtube: 2500, Twitter: 1400, }, } // 序列化對(duì)象 data, err := proto.Marshal(&elliot) if err != nil { log.Fatal("marshaling error: ", err) } // 反序列化對(duì)象進(jìn)行驗(yàn)證 newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // 輸出 `newElliot` 對(duì)象屬性進(jìn)行驗(yàn)證 fmt.Println(newElliot.GetName()) fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.SocialFollowers.GetTwitter()) fmt.Println(newElliot.SocialFollowers.GetYoutube()) }
運(yùn)行程序輸出結(jié)果:
Elliot 24 1400 2500
4. 總結(jié)
本文我們學(xué)習(xí)了Go應(yīng)用中如何使用 protocol buffer 數(shù)據(jù)格式。
到此這篇關(guān)于Golang Protocol Buffer案例詳解的文章就介紹到這了,更多相關(guān)Golang Protocol Buffer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的方法總結(jié)
項(xiàng)目開發(fā)中經(jīng)常會(huì)遇到多數(shù)據(jù)源同時(shí)使用的場景,比如冷熱數(shù)據(jù)的查詢等情況,所以接下來本文就來介紹一下如何使用實(shí)現(xiàn)自定義注解的形式來實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換吧2023-12-12SpringBoot?DataSource數(shù)據(jù)源實(shí)現(xiàn)自動(dòng)配置流程詳解
這篇文章主要介紹了SpringBoot?DataSource數(shù)據(jù)源實(shí)現(xiàn)自動(dòng)配置流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10詳解Java利用ExecutorService實(shí)現(xiàn)同步執(zhí)行大量線程
這篇文章主要介紹了Java利用ExecutorService實(shí)現(xiàn)同步執(zhí)行大量線程,ExecutorService可以維護(hù)我們的大量線程在操作臨界資源時(shí)的穩(wěn)定性。2017-03-03SpringMVC中RequestBody注解的List參數(shù)傳遞方式
這篇文章主要介紹了SpringMVC中RequestBody注解的List參數(shù)傳遞方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10springcloud檢索中間件?ElasticSearch?分布式場景的使用
單機(jī)的elasticsearch做數(shù)據(jù)存儲(chǔ),必然面臨兩個(gè)問題:海量數(shù)據(jù)存儲(chǔ)問題、單點(diǎn)故障問題,本文重點(diǎn)給大家介紹springcloud檢索中間件?ElasticSearch?分布式場景的運(yùn)用,感興趣的朋友跟隨小編一起看看吧2023-10-10Spring注解開發(fā)@Bean和@ComponentScan使用案例
這篇文章主要介紹了Spring注解開發(fā)@Bean和@ComponentScan使用案例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09