翻譯:Go 中 Protocol Buffer 教程

Go 中 Protocol Buffer 教程

歡迎程序員們!在這個教程裏面,咱們將學習如何使用protocol Buffers數據格式在你的go應用裏面. 咱們將詳細講述這種數據格式, 以及爲何這種數據格式優於傳統的數據格式例如xml甚至JSON. 在咱們寫更多複雜的例子以前,咱們將從一個簡單的例子開始編寫運行.git

在這章教的最後,你會對protoco Buffe有一個基礎的瞭解,而且你將能夠順利的寫出你本身更好的系統.程序員

視頻教程

https://www.youtube.com/embed/NoDRq6Twkts?ecver=2

Protocol Buffer數據類型

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的消息結構,其中包含了nameage兩個字段.

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

本文由 GCTT 原創編譯, Go 中文網 榮譽推出

相關文章
相關標籤/搜索