什么是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

最新文章

  1. Java 征途:行者的地图
  2. ASP.NET Web API 跨域访问(CORS)
  3. js获取可视区域高度
  4. [转载]基于TFS实践敏捷-项目管理
  5. lua的corroutine学习
  6. I/O之输出流 OutputStream类
  7. 如何发布得到.ipa文件
  8. Function-两个日期大小比较
  9. Guidelines for clock
  10. RT-Thread学习笔记(1)
  11. Scala中的语言特性是如何实现的(3) -- Trait
  12. Header,Tab,ListView三个在线性布局中,ListView向上滑动时,Tab标签悬停在顶部,然后Header向上滑出去,这个效果的做法
  13. NSDate详解及获取当前时间等常用操作
  14. java一维数组学习
  15. 在vue 中使用Stylus
  16. CLR类型设计之泛型(二)
  17. VC6安装错误——Error Launching acmboot.exe
  18. libguestfs手册(1): 架构
  19. 旷视研究院Detection组负责人
  20. H5 文字属性的缩写

热门文章

  1. C++如何保留2位小数输出
  2. 台式机安装CentOS7.6 Minimal ISO系统并增加图形化桌面
  3. OpenCA搭建
  4. Mac下好玩的终端命令
  5. 用java实现的微信公众号爬虫
  6. Leetcode 943. Find the Shortest Superstring(DP)
  7. 【桌面篇】Archlinux安装kde桌面
  8. Aajx
  9. Asp.Net Core Endpoint 终结点路由之中间件应用
  10. js中的0就是false,非0就是true。