歡迎程序員們!在這個教程裏面,咱們將學習如何使用protocol Buffers數據格式在你的go應用裏面. 咱們將詳細講述這種數據格式, 以及爲何這種數據格式優於傳統的數據格式例如xml甚至JSON. 在咱們寫更多複雜的例子以前,咱們將從一個簡單的例子開始編寫運行.git
在這章教的最後,你會對protoco Buffe有一個基礎的瞭解,而且你將能夠順利的寫出你本身更好的系統.程序員
https://www.youtube.com/embed/NoDRq6Twkts?ecver=2
Protocol buffers是基礎的數據格式, 和JSON,XML很是的類似, 都是用於存儲結構化的數據,都支持不少不一樣的語言使用並進行序列化和反序列化.github
這種數據格式最大的優勢就是它相比xml甚至JSON的大小要小不少. 這種格式是由Google開發的.Goggole是很是有名的公司,它的規模如此之大,他們作的每一件事情都產生深淵的影響.golang
假設有一我的, 咱們想用三個獨立的數據表示他:數組
<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]
若是你仔細觀察上面一行的編碼輸出, 你能夠看到從數組下標爲二的位置開始,ellio
就拼出來了.e
=69,l
=108等. 後面的字節表示我如今24歲了.this
可是這個編碼內容比咱們看到的要多的多. 我仍然在嘗試研究更多信息.若是你願意,我建議能夠查看更多Google關於protocol Buffer編碼的文檔: Protocol Buffer Encodinggoogle
雖然JSON和Protocol Buffer的大小几乎相同.可是隨着數據增大大於"入門"例子的數據,Json和protocol buffer使用的空間差距就變大了.編碼
& go get github.com/golang/protobuf $ go get github.com/golang/protobuf/proto
上面下載一些必須的包,用於運行簡單的例子.
($) export PATH=$PATH:$GOPATH/bin
進行上面的設置以後,你就能夠在終端使用protoc
這個命令了. 下面咱們就能夠定義protobuf的格式了,在這個例子裏,咱們將嘗試使用相同的person
這個對象,咱們用這個突出不一樣數據格式之間的區別.
首先咱們要指出要使用的協議類型, 在這個例子裏面咱們使用proto3
. 而後我把它做爲main
包的一部分.
最後咱們定義咱們想要的數據結構. 這個包含了Person
的消息結構,其中包含了name
和 age
兩個字段.
syntax="proto3"; package main; message Person { string name = 1; int32 age = 2; }
而後咱們使用protoc
命令編譯這個文件.
And we can then compile this using the protoc binary:
最終咱們準備好寫咱們GO代碼的全部東西. 咱們從定義一個Person
開始,並將這個對象編譯成protobuf
對象.
爲了瞭解它是如何存儲的,咱們使用fmt.Println(data)
打印存儲protobuf
對象的編碼數據.
package main 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) } // printing out our raw protobuf object fmt.Println(data) // let's go the other way and unmarshal // our byte array into an object we can modify // and use newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // print out our `newElliot` object // for good measure fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.GetName()) }
在運行以前,咱們須要將`test.pb.go'編譯經過以保證正常工做:
➜ src go run main.go test.pb.go [10 6 69 108 108 105 111 116 16 24] name:"Elliot" age:24
好了,咱們實現了一個很是簡單的例子並運行了它,可是在實際中,咱們常常遇到在messag的格式裏面有嵌套的字段,而且可能會修改一些它們的值.
如今咱們開始看看如何使用嵌套字段. 咱們繼續使用 Person
這個消息格式,咱們將添加一個社交媒體的追隨者的字段.
咱們用標準的字段以及自定義的SocialFollowers
消息字段組成Person這個消息格式,像下面這樣:
syntax="proto3"; package main; message SocialFollowers { int32 youtube = 1; int32 twitter = 2; } message Person { string name = 1; int32 age = 2; SocialFollowers socialFollowers = 3; }
再一次,咱們使用protoc
這個命令生成咱們想要的東西.
($) protoc --go_out=. *.proto
而後咱們再回到咱們的Go程序,咱們能夠用SocialFollowers
補充咱們的elliot
對象:
package main import ( "fmt" "log" "github.com/golang/protobuf/proto" ) func main() { elliot := Person{ Name: "Elliot", Age: 24, SocialFollowers: &SocialFollowers{ Youtube: 2500, Twitter: 1400, }, } data, err := proto.Marshal(&elliot) if err != nil { log.Fatal("marshaling error: ", err) } // let's go the other way and unmarshal // our protocol buffer into an object we can modify // and use newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // print out our `newElliot` object // for good measure fmt.Println(newElliot.GetName()) fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.SocialFollowers.GetTwitter()) fmt.Println(newElliot.SocialFollowers.GetYoutube()) }
咱們來最後一次運行它,咱們看到了全部咱們但願輸出的內容:
➜ src go run main.go test.pb.go Elliot 24 1400 2500
在這個教程裏面, 咱們瞭解瞭如何基於Go應用程序使用protocol buffer創建數據結構並運行,
但願這個教程對您有用。
via: https://tutorialedge.net/golang/go-protocol-buffer-tutorial/
做者:tutorialedge.net 譯者:amei 校對:校對者ID