什么是protobuf
protocol buffers 是一種語言無關、平臺無關、可擴展的序列化結構資料的方法,它可用于(資料)通信協議、資料存盤等,是一種靈活,高效,自動化機制的結構資料序列化方法-可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單,
protobuf與json區別
JSON與Protobuf都可以用來資訊交換,JSON是一種簡單的訊息格式,以文本方式傳輸,而Protobuf是以二進制方式進行傳輸,相較于JSON訊息體積會有明顯的縮小,所以傳輸速度也比JSON快,除此之外,Protobuf不僅僅是一種用于交換的訊息格式,還是用于定義交換訊息的規則和工具,目前基本支持所有的主流語言,
使用
先通過命令列進行安裝
go get -u github.com/golang/protobuf/protoc-gen-go
再創建一個名為test.proto的檔案,鍵入以下內容
syntax = "proto3";
package main;
message Test {
string label = 1;
int32 type = 2;
repeated int64 reps = 3;
}
我們以proto3為例,創建一個叫Test的message,設定三個屬性,label、type和int64,repeated對應生成的Go語言變數型別為切片,下面在命令列執行protoc來生成Go檔案,
protoc --go_out=./ test.proto
可以看到在根目錄中生成了一個名為test.pb.go的檔案
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test.proto
package main
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
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.ProtoPackageIsVersion3 // please upgrade the proto package
type Test struct {
Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
Type int32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
Reps []int64 `protobuf:"varint,3,rep,packed,name=reps,proto3" json:"reps,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Test) Reset() { *m = Test{} }
func (m *Test) String() string { return proto.CompactTextString(m) }
func (*Test) ProtoMessage() {}
func (*Test) Descriptor() ([]byte, []int) {
return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
}
func (m *Test) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Test.Unmarshal(m, b)
}
func (m *Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Test.Marshal(b, m, deterministic)
}
func (m *Test) XXX_Merge(src proto.Message) {
xxx_messageInfo_Test.Merge(m, src)
}
func (m *Test) XXX_Size() int {
return xxx_messageInfo_Test.Size(m)
}
func (m *Test) XXX_DiscardUnknown() {
xxx_messageInfo_Test.DiscardUnknown(m)
}
var xxx_messageInfo_Test proto.InternalMessageInfo
func (m *Test) GetLabel() string {
if m != nil {
return m.Label
}
return ""
}
func (m *Test) GetType() int32 {
if m != nil {
return m.Type
}
return 0
}
func (m *Test) GetReps() []int64 {
if m != nil {
return m.Reps
}
return nil
}
func init() {
proto.RegisterType((*Test)(nil), "main.Test")
}
func init() {
proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e)
}
var fileDescriptor_c161fcfdc0c3ff1e = []byte{
// 104 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x49, 0x2d, 0x2e,
0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0x72, 0xe1, 0x62,
0x09, 0x49, 0x2d, 0x2e, 0x11, 0x12, 0xe1, 0x62, 0xcd, 0x49, 0x4c, 0x4a, 0xcd, 0x91, 0x60, 0x54,
0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x84, 0x84, 0xb8, 0x58, 0x4a, 0x2a, 0x0b, 0x52, 0x25, 0x98,
0x14, 0x18, 0x35, 0x58, 0x83, 0xc0, 0x6c, 0x90, 0x58, 0x51, 0x6a, 0x41, 0xb1, 0x04, 0xb3, 0x02,
0xb3, 0x06, 0x73, 0x10, 0x98, 0x9d, 0xc4, 0x06, 0x36, 0xd2, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff,
0x7b, 0xa2, 0xc6, 0x01, 0x60, 0x00, 0x00, 0x00,
}
我們在main檔案中進行序列化測驗
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
)
func main() {
test := &Test{
Label: "a",
Type: 32,
Reps: []int64{10, 11},
}
resp, err := proto.Marshal(test)
if err != nil {
fmt.Println(err)
}
fmt.Println(resp)
}
protobuf生成了一個名為Test的結構體,其中有三個成員屬性,正好與test.proto檔案對應,執行poroto.Marshal方法可以對結構體進行序列化,后續就可以借助RPC或HTTP的載體進行傳輸,
Golang組件示例代碼倉庫,歡迎star
https://github.com/EnochZg/golang-examples
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/30708.html
標籤:Go
