翻譯:Go 中 Protocol Buffer 教程
Go 中 Protocol Buffer 教程
歡迎程式設計師們!在這個教程裡面,我們將學習如何使用protocol Buffers資料格式在你的go應用裡面. 我們將詳細講述這種資料格式, 以及為什麼這種資料格式優於傳統的資料格式例如xml甚至JSON. 在我們寫更多複雜的例子之前,我們將從一個簡單的例子開始編寫執行.
在這章教的最後,你會對protoco Buffe有一個基礎的瞭解,並且你將可以順利的寫出你自己更好的系統.
視訊教程
https://www.youtube.com/embed/NoDRq6Twkts?ecver=2
Protocol Buffer資料型別
Protocol buffers是基礎的資料格式, 和JSON,XML非常的相似, 都是用於儲存結構化的資料,都支援很多不同的語言使用並進行序列化和反序列化.
這種資料格式最大的優點就是它相比xml甚至JSON的大小要小很多. 這種格式是由Google開發的.Goggole是非常有名的公司,它的規模如此之大,他們做的每一件事情都產生深淵的影響.
假設有一個人, 我們想用三個獨立的資料表示他:
<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歲了.
但是這個編碼內容比我們看到的要多的多. 我仍然在嘗試研究更多資訊.如果你願意,我建議可以檢視更多Google關於protocol Buffer編碼的文件:
雖然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