goprotobuf基本使用

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

如果你對Google Protocol Buffer不瞭解,可以先看下我這篇文章裡收集的中文資料:關於Google Protocol Buffer的中文資料
源碼地址:https://code.google.com/p/goprotobuf/
詳細的介紹:https://code.google.com/p/goprotobuf/source/browse/README
介紹:
This software has two parts: a ‘protocol compiler plugin’ that generates Go source files that, once compiled, can access and manage protocol buffers; and a library that implements run-time support for encoding (marshaling), decoding (unmarshaling), and accessing protocol buffers.
大意:
該軟體包含兩部分:protoc-gen-go:一旦使用’協議編譯器外掛程式‘編譯,會產生一些go的源碼檔案,可以訪問和管理protocol buffers;proto:是一個實現運行時支援,為編碼(編組),解碼(解編)的庫,和訪問protocol buffers。
簡單的說,protoc-gen-go是一個編譯器,用來把 *.proto協議檔案,編譯產生 *.pb.go檔案。再接下來的例子,我們會介紹如何使用它。
而proto需要包含到我們的軟體裡,去將訊息編碼為位元據,或者將位元據還原為訊息對象。
源碼下載:
go get -u code.google.com/p/goprotobuf/{proto,protoc-gen-go}
或者直接下載源碼到自己的項目裡:
hg clone https://code.google.com/p/goprotobuf/
如:

編譯:

編譯成功後,我們會發現bin目錄下,會產生protoc-gen-go檔案,以及pkg目錄下會產生對應的庫檔案。
接下來,我們編寫測試一個例子:
首先,編寫test.proto,內容如下:

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;
}
}

接著,編寫Makefile檔案,用於產生*.pb.go檔案,內容如下:

include ../code.google.com/p/goprotobuf/Make.protobuf

all:regenerate

regenerate:
rm -f test.pb.go
make test.pb.go

# The following rules are just aids to development. Not needed for typical testing.

diff:regenerate
hg diff test.pb.go

restore:
cp test.pb.go.golden test.pb.go

preserve:
cp test.pb.go test.pb.go.golden

終端下,make以後,我們會看到產生對應的test.pb.go檔案,內容如下:

// Code generated by protoc-gen-go.
// source: test.proto
// DO NOT EDIT!

package example

import proto "code.google.com/p/goprotobuf/proto"
import json "encoding/json"
import math "math"

// Reference proto, json, and math imports to suppress error if they are not otherwise used.
var _ = proto.Marshal
var _ = &json.SyntaxError{}
var _ = math.Inf

type FOO int32

const (
FOO_X FOO = 17
)

var FOO_name = map[int32]string{
17: "X",
}
var FOO_value = map[string]int32{
"X": 17,
}

func (x FOO) Enum() *FOO {
p := new(FOO)
*p = x
return p
}
func (x FOO) String() string {
return proto.EnumName(FOO_name, int32(x))
}
func (x FOO) MarshalJSON() ([]byte, error) {
return json.Marshal(x.String())
}
func (x *FOO) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO")
if err != nil {
return err
}
*x = FOO(value)
return nil
}

type Test struct {
Label *string protobuf:"bytes,1,req,name=label" json:"label,omitempty"
Type *int32 protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"
Reps []int64 protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"
Optionalgroup *Test_OptionalGroup protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"
XXX_unrecognized []byte json:"-"
}

func (this *Test) Reset() { *this = Test{} }
func (this *Test) String() string { return proto.CompactTextString(this) }
func (*Test) ProtoMessage() {}

const Default_Test_Type int32 = 77

func (this *Test) GetLabel() string {
if this != nil && this.Label != nil {
return *this.Label
}
return ""
}

func (this *Test) GetType() int32 {
if this != nil && this.Type != nil {
return *this.Type
}
return Default_Test_Type
}

func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
if this != nil {
return this.Optionalgroup
}
return nil
}

type Test_OptionalGroup struct {
RequiredField *string protobuf:"bytes,5,req" json:"RequiredField,omitempty"
}

func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} }

func (this *Test_OptionalGroup) GetRequiredField() string {
if this != nil && this.RequiredField != nil {
return *this.RequiredField
}
return ""
}

func init() {
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
}

最後,編寫測試代碼如下:

package main

import (
"log"

"code.google.com/p/goprotobuf/proto"
"example"
"fmt"
)

func main() {
test := &example.Test{
Label: proto.String("hello"),
Type: proto.Int32(17),
Optionalgroup: &example.Test_OptionalGroup{
RequiredField: proto.String("good bye"),
},
}
// print test by string.
fmt.Println(test.String())
data, err := proto.Marshal(test)
if err != nil {
log.Fatal("marshaling error: ", err)
}
// print data
fmt.Println(data)
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())
}
// etc.
}

編譯運行,結果如下:

這裡只是簡單介紹並編寫了個測試例子,許多細節並沒有介紹,以後有機會再跟大家分享。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.