如何在go中使用protobuf

protobuf是Google開發出來的一個語言無關、平臺無關的數據序列化工具,在rpc或tcp通訊等不少場景均可以使用。通俗來說,若是客戶端和服務端使用的是不一樣的語言,那麼在服務端定義一個數據結構,經過protobuf轉化爲字節流,再傳送到客戶端解碼,就能夠獲得對應的數據結構。這就是protobuf神奇的地方。而且,它的通訊效率極高,「一條消息數據,用protobuf序列化後的大小是json的10分之一,xml格式的20分之一,是二進制序列化的10分之一」。git

安裝github

  • 編譯安裝protobuf的編譯器protocgolang

wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
        tar zxvf protobuf-2.6.1.tar.gz
        cd protobuf-2.6.1./configure
        make
        make install
        執行 protoc  -h 查看安裝是否成功
  • 安裝插件 protoc-gen-go,它是一個go程序,編譯它以後將可執行文件執行路徑寫入環境變量json

go get github.com/golang/protobuf/protoc-gen-go
  • 獲取proto數據結構

go get github.com/golang/protobuf/proto

在go中使用tcp

protobuf的使用方法是將數據結構寫入到.proto文件中,使用protoc編譯器編譯(間接使用了插件)獲得一個新的go包,裏面包含go中能夠使用的數據結構和一些輔助方法。工具

編寫test.proto文件ui

package example;
    
    enum FOO { X = 17; };
    
    message Test {
      required string label = 1;
      optional int32 type = 2 [default=77];
      repeated int64 reps = 3;
      optional group OptionalGroup = 4 {
        required string RequiredField = 5;
      }
    }
    編譯:
    執行 protoc --go_out=. *.proto 生成 test.pb.go 文件
    將test.pb.go文件放入example文件夾(對應上面package)中,做爲example包

trygoogle

package main

    import (
        "log"

        "github.com/golang/protobuf/proto"
        "example"
    )

    func main() {
        test := &example.Test {
            Label: proto.String("hello"),
            Type:  proto.Int32(17),
            Reps:  []int64{1, 2, 3},
            Optionalgroup: &example.Test_OptionalGroup {
                RequiredField: proto.String("good bye"),
            },
        }
        data, err := proto.Marshal(test)
        if err != nil {
            log.Fatal("marshaling error: ", err)
        }
        newTest := &example.Test{}
        err = proto.Unmarshal(data, newTest)
        if err != nil {
            log.Fatal("unmarshaling error: ", err)
        }
        // Now test and newTest contain the same data.
        if test.GetLabel() != newTest.GetLabel() {
            log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
        }
        //test.GetOptionalgroup().GetRequiredField()
        //etc
    }

一些對應關係編碼

  • message Test對爲 struct 結構,其屬性字段有了對應的get方法,在go中能夠使用test.GetLabel()、test.GetType()獲取test對象的屬性

  • OptionalGroup對應爲 struct中的內嵌struct

  • proto文件中repeated屬性對於slice結構

  • test.Reset()能夠使其全部屬性置爲0值

  • 使用Marshal和Unmarshal能夠輕鬆的編碼和解碼

這些只是一些特性,想要仔細研究能夠查看github上的wiki:https://github.com/golang/pro...