golang中Protobuf如何使用

這篇文章給大家介紹golang中Protobuf如何使用,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

成都創(chuàng)新互聯(lián)公司專(zhuān)注于三河企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。三河網(wǎng)站建設(shè)公司,為三河等地區(qū)提供建站服務(wù)。全流程按需定制開(kāi)發(fā),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

?? protobuf是一種高效的數(shù)據(jù)傳輸格式(Google's data interchange format),且與語(yǔ)言無(wú)關(guān),protobuf和json是基于http服務(wù)中最常見(jiàn)的兩種數(shù)據(jù)格式。今天來(lái)學(xué)習(xí)基于golang的protobuf相關(guān)內(nèi)容。

要想使用protobuf,需要4步:

  1. 下載安裝google protocol buffer 編譯器:https://github.com/google/protobuf/releases/tag/v3.5.1

  2. 下載安裝golang protobuf plugin:https://github.com/golang/protobuf
    使用go tools安裝:go get -u github.com/golang/protobuf/protoc-gen-go

  3. 按照protobuf 語(yǔ)法規(guī)則編寫(xiě).proto文件

  4. 將proto文件編譯成golang代碼模型
    protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto
    -IPATH, --proto_path=PATH 指定import路徑
    --go_out 指定生成go代碼路徑(同理--java_out是指定java生成路徑)  


下面以一個(gè)實(shí)際例子來(lái)說(shuō)明:
addressbook.proto

syntax = "proto3";
package test.protobuf.tutorial;
message Person{
    string name  = 1;//姓名
    int32  id    = 2;//id編號(hào)
    string email = 3;//郵箱
    enum PhoneType { //枚舉類(lèi)型(電話(huà)類(lèi)型)
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }
    message PhoneNumber{
        string    number = 1;
        PhoneType type   = 2;
    }
    repeated PhoneNumber phones = 4; //repeated可理解為動(dòng)態(tài)數(shù)組
}

// Our address book file is just one of these.
message AddressBook {
    repeated Person people = 1;
}

編譯生成go文件。protoc會(huì)調(diào)用protoc-go-gen來(lái)生成go文件
.
├── addressbook.proto
└── src
└── addressbook.pb.go
protoc --go_out=./src addressbook.proto

addressbook.pb.go

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

/*
Package test_protobuf_tutorial is a generated protocol buffer package.

It is generated from these files:
    addressbook.proto

It has these top-level messages:
    Person
    AddressBook
*/
package test_protobuf_tutorial

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type Person_PhoneType int32

const (
    Person_MOBILE Person_PhoneType = 0
    Person_HOME   Person_PhoneType = 1
    Person_WORK   Person_PhoneType = 2
)

var Person_PhoneType_name = map[int32]string{
    0: "MOBILE",
    1: "HOME",
    2: "WORK",
}
var Person_PhoneType_value = map[string]int32{
    "MOBILE": 0,
    "HOME":   1,
    "WORK":   2,
}

func (x Person_PhoneType) String() string {
    return proto.EnumName(Person_PhoneType_name, int32(x))
}
func (Person_PhoneType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }

type Person struct {
    Name   string                `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
    Id     int32                 `protobuf:"varint,2,opt,name=id" json:"id,omitempty"`
    Email  string                `protobuf:"bytes,3,opt,name=email" json:"email,omitempty"`
    Phones []*Person_PhoneNumber `protobuf:"bytes,4,rep,name=phones" json:"phones,omitempty"`
}

func (m *Person) Reset()                    { *m = Person{} }
func (m *Person) String() string            { return proto.CompactTextString(m) }
func (*Person) ProtoMessage()               {}
func (*Person) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

func (m *Person) GetName() string {
    if m != nil {
        return m.Name
    }
    return ""
}

func (m *Person) GetId() int32 {
    if m != nil {
        return m.Id
    }
    return 0
}

func (m *Person) GetEmail() string {
    if m != nil {
        return m.Email
    }
    return ""
}

func (m *Person) GetPhones() []*Person_PhoneNumber {
    if m != nil {
        return m.Phones
    }
    return nil
}

type Person_PhoneNumber struct {
    Number string           `protobuf:"bytes,1,opt,name=number" json:"number,omitempty"`
    Type   Person_PhoneType `protobuf:"varint,2,opt,name=type,enum=test.protobuf.tutorial.Person_PhoneType" json:"type,omitempty"`
}

func (m *Person_PhoneNumber) Reset()                    { *m = Person_PhoneNumber{} }
func (m *Person_PhoneNumber) String() string            { return proto.CompactTextString(m) }
func (*Person_PhoneNumber) ProtoMessage()               {}
func (*Person_PhoneNumber) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }

func (m *Person_PhoneNumber) GetNumber() string {
    if m != nil {
        return m.Number
    }
    return ""
}

func (m *Person_PhoneNumber) GetType() Person_PhoneType {
    if m != nil {
        return m.Type
    }
    return Person_MOBILE
}

// Our address book file is just one of these.
type AddressBook struct {
    People []*Person `protobuf:"bytes,1,rep,name=people" json:"people,omitempty"`
}

func (m *AddressBook) Reset()                    { *m = AddressBook{} }
func (m *AddressBook) String() string            { return proto.CompactTextString(m) }
func (*AddressBook) ProtoMessage()               {}
func (*AddressBook) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

func (m *AddressBook) GetPeople() []*Person {
    if m != nil {
        return m.People
    }
    return nil
}

func init() {
    proto.RegisterType((*Person)(nil), "test.protobuf.tutorial.Person")
    proto.RegisterType((*Person_PhoneNumber)(nil), "test.protobuf.tutorial.Person.PhoneNumber")
    proto.RegisterType((*AddressBook)(nil), "test.protobuf.tutorial.AddressBook")
    proto.RegisterEnum("test.protobuf.tutorial.Person_PhoneType", Person_PhoneType_name, Person_PhoneType_value)
}

func init() { proto.RegisterFile("addressbook.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
    // 265 bytes of a gzipped FileDescriptorProto
    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xc1, 0x4b, 0xbc, 0x50,
    0x10, 0xc7, 0x7f, 0xba, 0xee, 0xe3, 0xb7, 0x23, 0x2c, 0x36, 0xc4, 0x22, 0x1d, 0x42, 0x3c, 0x49,
    0x81, 0x87, 0x0d, 0x3a, 0x75, 0x49, 0x10, 0x8a, 0xda, 0x5c, 0x1e, 0x41, 0x67, 0xcd, 0x89, 0x64,
    0xd5, 0x79, 0xe8, 0xf3, 0xb0, 0xff, 0x49, 0x7f, 0x6e, 0xf8, 0x94, 0xe8, 0x10, 0xd1, 0xed, 0x3b,
    0xc3, 0x67, 0xf8, 0xcc, 0x0c, 0x9c, 0xe4, 0x65, 0xd9, 0x51, 0xdf, 0x17, 0xcc, 0x87, 0x58, 0x75,
    0xac, 0x19, 0x37, 0x9a, 0x7a, 0x3d, 0xe5, 0x62, 0x78, 0x8b, 0xf5, 0xa0, 0xb9, 0xab, 0xf2, 0x3a,
    0xfc, 0xb0, 0x41, 0xec, 0xa9, 0xeb, 0xb9, 0x45, 0x04, 0xa7, 0xcd, 0x1b, 0xf2, 0xad, 0xc0, 0x8a,
    0x56, 0xd2, 0x64, 0x5c, 0x83, 0x5d, 0x95, 0xbe, 0x1d, 0x58, 0xd1, 0x52, 0xda, 0x55, 0x89, 0xa7,
    0xb0, 0xa4, 0x26, 0xaf, 0x6a, 0x7f, 0x61, 0xa0, 0xa9, 0xc0, 0x04, 0x84, 0x7a, 0xe7, 0x96, 0x7a,
    0xdf, 0x09, 0x16, 0x91, 0xbb, 0xbd, 0x88, 0x7f, 0xb6, 0xc5, 0x93, 0x29, 0xde, 0x8f, 0xf0, 0xd3,
    0xd0, 0x14, 0xd4, 0xc9, 0x79, 0xf2, 0xec, 0x15, 0xdc, 0x6f, 0x6d, 0xdc, 0x80, 0x68, 0x4d, 0x9a,
    0xd7, 0x99, 0x2b, 0xbc, 0x01, 0x47, 0x1f, 0x15, 0x99, 0x95, 0xd6, 0xdb, 0xe8, 0x2f, 0xa2, 0xe7,
    0xa3, 0x22, 0x69, 0xa6, 0xc2, 0x4b, 0x58, 0x7d, 0xb5, 0x10, 0x40, 0xec, 0xb2, 0xe4, 0xfe, 0x31,
    0xf5, 0xfe, 0xe1, 0x7f, 0x70, 0xee, 0xb2, 0x5d, 0xea, 0x59, 0x63, 0x7a, 0xc9, 0xe4, 0x83, 0x67,
    0x87, 0x29, 0xb8, 0xb7, 0xd3, 0x1f, 0x13, 0xe6, 0x03, 0x5e, 0x83, 0x50, 0xc4, 0xaa, 0x1e, 0x1f,
    0x34, 0x1e, 0x79, 0xfe, 0xbb, 0x5b, 0xce, 0x74, 0x21, 0x0c, 0x71, 0xf5, 0x19, 0x00, 0x00, 0xff,
    0xff, 0x38, 0xba, 0x26, 0x8c, 0x95, 0x01, 0x00, 0x00,
}

ok,生成模型代碼后,我們就可以使用protobuf協(xié)議來(lái)對(duì)數(shù)據(jù)進(jìn)行編解碼了

 //將數(shù)據(jù)編碼成protobuf 二進(jìn)制格式--Writing a Message
 func EncodeAddressBook (book *pb.AddressBook)(out []byte, err error) {
    // Write the new address book back to disk.
    out, err = proto.Marshal(book)
    if err != nil {
        log.Println("Failed to encode address book:", err)
        return nil,err
    }
    if err := ioutil.WriteFile("addressbook_proto.data", out, 0644); err != nil {
        log.Fatalln("Failed to write address book:", err)
        return nil,err
    }
    fmt.Println("[Debug]: ", out)
    return
}
  //將二進(jìn)制數(shù)據(jù)解碼為golang 數(shù)據(jù)結(jié)構(gòu) --Reading a Message
 func DecodeAddressBook(in []byte) (book *pb.AddressBook, err error){
    // Read the existing address book.
    book = &pb.AddressBook{}
    if err := proto.Unmarshal(in, book); err != nil {
        log.Println("Failed to parse address book:", err)
        return nil,err
    }
    return
}

關(guān)于golang中Protobuf如何使用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

文章名稱(chēng):golang中Protobuf如何使用
URL鏈接:http://muchs.cn/article2/ighjic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站設(shè)計(jì)公司虛擬主機(jī)、網(wǎng)站排名、建站公司、網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)