2019独角兽企业重金招聘Python工程师标准>>>

protobuf是一个跨语言的传输协议格式,其功能和json类似. protobuf和json不同的是proto使用二进制进行传输,速度上会比json效率高. 但是在可读性上比json差.

protobuf底层使用C++实现的.但现在已经支持很多的语言使用了.目前支持:C++,java,python,objective-c,c#, javascript, ruby, go, php, Dart. 在这里讲protobuf在go中的使用.我使用的环境是ubuntu 16.04

在使用之前需要安装proto的基础包.基础包是C++编写的,所以需要用到编译C++一些常规的环境,这里不具体介绍.

安装go的环境

再者获取go相关的插件包:go get -u github.com/golang/protobuf

获取之后进入相应的文件夹,使用go build , go install进行编译和安装.使用命令:proto --version测试是否成功安装.

chenmei@bogon:~/go/src/test/protobuf$ protoc --version
libprotoc 2.6.1

下面我们就看一个使用的例子,先写一个proto的原文件,这里以学生以及和学生管理的考试成绩为例子:

syntax = "proto2";
package pb;message Course {required string name = 1;required int32 score = 2;
}
message Student {required int32 UUID = 1;required string Username = 2;repeated Course courses = 3;
}message Studentlist {repeated Student students = 1;
}

上面就定义了课程,学生,以及学生的列表这几个结构.

使用命令进行转换:

protoc --go_out=. Studentlist.proto

当转换完成会生成如下的文件:

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: Studentlist.protopackage pbimport (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 packagetype Course struct {Name                 *string  `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`Score                *int32   `protobuf:"varint,2,req,name=score" json:"score,omitempty"`XXX_NoUnkeyedLiteral struct{} `json:"-"`XXX_unrecognized     []byte   `json:"-"`XXX_sizecache        int32    `json:"-"`
}func (m *Course) Reset()         { *m = Course{} }
func (m *Course) String() string { return proto.CompactTextString(m) }
func (*Course) ProtoMessage()    {}
func (*Course) Descriptor() ([]byte, []int) {return fileDescriptor_14fc7c21f335a148, []int{0}
}func (m *Course) XXX_Unmarshal(b []byte) error {return xxx_messageInfo_Course.Unmarshal(m, b)
}
func (m *Course) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {return xxx_messageInfo_Course.Marshal(b, m, deterministic)
}
func (m *Course) XXX_Merge(src proto.Message) {xxx_messageInfo_Course.Merge(m, src)
}
func (m *Course) XXX_Size() int {return xxx_messageInfo_Course.Size(m)
}
func (m *Course) XXX_DiscardUnknown() {xxx_messageInfo_Course.DiscardUnknown(m)
}var xxx_messageInfo_Course proto.InternalMessageInfofunc (m *Course) GetName() string {if m != nil && m.Name != nil {return *m.Name}return ""
}func (m *Course) GetScore() int32 {if m != nil && m.Score != nil {return *m.Score}return 0
}type Student struct {UUID                 *int32    `protobuf:"varint,1,req,name=UUID" json:"UUID,omitempty"`Username             *string   `protobuf:"bytes,2,req,name=Username" json:"Username,omitempty"`Courses              []*Course `protobuf:"bytes,3,rep,name=courses" json:"courses,omitempty"`XXX_NoUnkeyedLiteral struct{}  `json:"-"`XXX_unrecognized     []byte    `json:"-"`XXX_sizecache        int32     `json:"-"`
}func (m *Student) Reset()         { *m = Student{} }
func (m *Student) String() string { return proto.CompactTextString(m) }
func (*Student) ProtoMessage()    {}
func (*Student) Descriptor() ([]byte, []int) {return fileDescriptor_14fc7c21f335a148, []int{1}
}func (m *Student) XXX_Unmarshal(b []byte) error {return xxx_messageInfo_Student.Unmarshal(m, b)
}
func (m *Student) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {return xxx_messageInfo_Student.Marshal(b, m, deterministic)
}
func (m *Student) XXX_Merge(src proto.Message) {xxx_messageInfo_Student.Merge(m, src)
}
func (m *Student) XXX_Size() int {return xxx_messageInfo_Student.Size(m)
}
func (m *Student) XXX_DiscardUnknown() {xxx_messageInfo_Student.DiscardUnknown(m)
}var xxx_messageInfo_Student proto.InternalMessageInfofunc (m *Student) GetUUID() int32 {if m != nil && m.UUID != nil {return *m.UUID}return 0
}func (m *Student) GetUsername() string {if m != nil && m.Username != nil {return *m.Username}return ""
}func (m *Student) GetCourses() []*Course {if m != nil {return m.Courses}return nil
}type Studentlist struct {Students             []*Student `protobuf:"bytes,1,rep,name=students" json:"students,omitempty"`XXX_NoUnkeyedLiteral struct{}   `json:"-"`XXX_unrecognized     []byte     `json:"-"`XXX_sizecache        int32      `json:"-"`
}func (m *Studentlist) Reset()         { *m = Studentlist{} }
func (m *Studentlist) String() string { return proto.CompactTextString(m) }
func (*Studentlist) ProtoMessage()    {}
func (*Studentlist) Descriptor() ([]byte, []int) {return fileDescriptor_14fc7c21f335a148, []int{2}
}func (m *Studentlist) XXX_Unmarshal(b []byte) error {return xxx_messageInfo_Studentlist.Unmarshal(m, b)
}
func (m *Studentlist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {return xxx_messageInfo_Studentlist.Marshal(b, m, deterministic)
}
func (m *Studentlist) XXX_Merge(src proto.Message) {xxx_messageInfo_Studentlist.Merge(m, src)
}
func (m *Studentlist) XXX_Size() int {return xxx_messageInfo_Studentlist.Size(m)
}
func (m *Studentlist) XXX_DiscardUnknown() {xxx_messageInfo_Studentlist.DiscardUnknown(m)
}var xxx_messageInfo_Studentlist proto.InternalMessageInfofunc (m *Studentlist) GetStudents() []*Student {if m != nil {return m.Students}return nil
}func init() {proto.RegisterType((*Course)(nil), "pb.Course")proto.RegisterType((*Student)(nil), "pb.Student")proto.RegisterType((*Studentlist)(nil), "pb.Studentlist")
}func init() { proto.RegisterFile("Studentlist.proto", fileDescriptor_14fc7c21f335a148) }var fileDescriptor_14fc7c21f335a148 = []byte{// 158 bytes of a gzipped FileDescriptorProto0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x0c, 0x2e, 0x29, 0x4d,0x49, 0xcd, 0x2b, 0xc9, 0xc9, 0x2c, 0x2e, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a,0x48, 0x52, 0x52, 0xe5, 0x62, 0x73, 0xce, 0x2f, 0x2d, 0x2a, 0x4e, 0x15, 0xe2, 0xe1, 0x62, 0xc9,0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60, 0xd2, 0xe0, 0x14, 0xe2, 0xe5, 0x62, 0x2d, 0x4e, 0xce,0x2f, 0x4a, 0x95, 0x60, 0x52, 0x60, 0xd2, 0x60, 0x55, 0x72, 0xe3, 0x62, 0x87, 0xea, 0x07, 0xa9,0x0b, 0x0d, 0xf5, 0x74, 0x01, 0xab, 0x63, 0x15, 0x12, 0xe0, 0xe2, 0x08, 0x2d, 0x4e, 0x2d, 0x02,0xeb, 0x64, 0x02, 0xeb, 0x94, 0xe6, 0x62, 0x4f, 0x06, 0x9b, 0x58, 0x2c, 0xc1, 0xac, 0xc0, 0xac,0xc1, 0x6d, 0xc4, 0xa5, 0x57, 0x90, 0xa4, 0x07, 0xb1, 0x44, 0x49, 0x87, 0x8b, 0x1b, 0xc9, 0x1d,0x42, 0xb2, 0x5c, 0x1c, 0xc5, 0x10, 0x6e, 0xb1, 0x04, 0x23, 0x58, 0x31, 0x37, 0x48, 0x31, 0x54,0x09, 0x20, 0x00, 0x00, 0xff, 0xff, 0x66, 0x6d, 0x7d, 0x4c, 0xb4, 0x00, 0x00, 0x00,
}

下面看main.go的写法,在main里面先对数据进行序列化,然后再反序列化.

package mainimport ("fmt""test/protobuf/pb""github.com/golang/protobuf/proto"
)func main() {course11 := pb.Course{Name: proto.String("math"),Score: proto.Int32(99),}course12 := pb.Course {Name: proto.String("english"),Score: proto.Int32(90),}course21 := pb.Course{Name: proto.String("math"),Score: proto.Int32(94),}course22 := pb.Course {Name: proto.String("english"),Score: proto.Int32(95),}student1 := pb.Student {UUID: proto.Int32(1),Username: proto.String("mei.chen"),Courses: []*pb.Course{&course11, &course12},}student2 := pb.Student {UUID: proto.Int32(2),Username: proto.String("he.he"),Courses: []*pb.Course{&course21, &course22},}students := pb.Studentlist {Students: []*pb.Student{&student1,&student2},}//序列化:data, err := proto.Marshal(&students)if err != nil {fmt.Println("marshal error", err)}fmt.Println("marshal data:",data)//反序列化var list pb.Studentlisterr = proto.Unmarshal(data, &list)if err != nil {fmt.Println("unmarshal error:",err)}for _, student := range list.Students {fmt.Println("------------------------------------------")fmt.Println("sudent name: ",student.GetUsername())for _, course := range student.Courses {fmt.Println("course: ",course.GetName())fmt.Println("score: ",course.GetScore())}}
}

输出结果如下:

marshal data: [10 35 8 1 18 8 109 101 105 46 99 104 101 110 26 8 10 4 109 97 116 104 16 99 26 11 10 7 101 110 103 108 105 115 104 16 90 10 32 8 2 18 5 104 101 46 104 101 26 8 10 4 109 97 116 104 16 94 26 11 10 7 101 110 103 108 105 115 104 16 95]
------------------------------------------
sudent name:  mei.chen
course:  math
score:  99
course:  english
score:  90
------------------------------------------
sudent name:  he.he
course:  math
score:  94
course:  english
score:  95

这里需要注意的地方:

1.在proto文件中定义的字段如果首字母是小写,那么在转换的时候会变成大写.

2.在proto中定义的类型其实都是指针,例如string,需要使用proto.String转为指针类型. 这个你可以在转换后的文件中可以看到.

作者:amei 链接:http://114.116.145.166:5897/blogs/amei/articles/2019/04/02/1554195518207

转载于:https://my.oschina.net/u/1013544/blog/3031466

protobuf在go中的应用相关推荐

  1. 《Dotnet9》系列-Google ProtoBuf在C#中的简单应用

    简介 什么是 Google Protocol Buffer? 假如您在网上搜索,应该会得到类似这样的文字介绍: Google Protocol Buffer( 简称 Protobuf) 是 Googl ...

  2. php protobuf 性能,php中使用protobuffer

    Protobuf 简介 protobuf(Protocol buffers)是谷歌出品的跨平台.跨语言.可扩展的数据传输及存储的协议,是高效的数据压缩编码方式之一. Protocol buffers ...

  3. C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信

    From: http://www.jb51.net/article/82795.htm 这篇文章主要介绍了C#使用Protocol Buffer(ProtoBuf)进行Unity的Socket通信的实 ...

  4. protobuf在java中使用_记录:Protocol Buffers(protobuf)在Java开发中使用

    1.编写一个.proto文件命名为:addressbook.proto,该文件内容来自protocal-buffers官网 2.使用protoc-2.6.0-win32.zip解压后的protoc.e ...

  5. ProtoBuf lite版中使用Any

    版本3.13.0 因为google/protobuf/any.proto,不带option optimize_for = LITE_RUNTIME;且没有编译到lite版中,所以我们自己实现一个any ...

  6. Protobuf在Unity中的通讯使用

    代码很简单直接上了 using ProtoBuf; using UnityEngine; using System.IO; using System; public class Test2 : Mon ...

  7. UNITY性能优化✨ProtoBuf 在 Unity 中的详细使用教程

    文章目录

  8. protobuf中 repeated[Ptr]Field的序列化

    message Test1 {required int32 a = 1; }Test1 t1; t1.set_a(150); 序列化之后的结果是 08 96 01. 其中08 >>3 == ...

  9. protobuf在java应用中通过反射动态创建对象

    2019独角兽企业重金招聘Python工程师标准>>> ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输,苦于protobuf接受客户端的数据时是 ...

最新文章

  1. 兰艳艳:理想温暖10年科研路,女性可以柔和,更要自信、专业 | 妇女节特辑...
  2. 工作那些事儿(12)- 缓存
  3. website for .Net Core
  4. Python中安装bs4后,pycharm依然报错ModuleNotFoundError: No module named 'bs4'
  5. 使用Spring工厂模式管理多个类实现同一个接口
  6. 【渝粤题库】广东开放大学 文化产业概论 形成性考核
  7. linux-使用基础-自动补全-快捷键-历史命令-别名
  8. impdp oracle 只导入表结构_oracle数据库怎么导入dmp,只导入数据不导入表结构?...
  9. Codeforces Round #354 (Div. 2) A. Nicholas and Permutation
  10. 应用安全-安全设备-Waf系列-软Waf-云锁
  11. 车辆十四自由度动力学建模分析
  12. vue 项目登录注册中如何使用滑块去校验
  13. 必应图片搜索——产品分析
  14. 看到Apache协议 BSD协议,你知道啥意思吗
  15. mfc匹配关键字颜色显示_如何在多台显示器上匹配颜色
  16. Git使用简介一(入门级)
  17. ubuntu14.04安装nvidia-GTK-1060驱动后黑屏
  18. 世界上第一个微处理器真的是Intel 4004吗?其实这是个很复杂的故事…
  19. 考研英语二2017阅读理解Text3
  20. MFC使用Windows API实现U盘插拔检测,获取U盘容量,U盘内容移动删除,开启和关闭U盘以及获取盘符

热门文章

  1. 如何在Web应用程序中使用TWAIN驱动程序的自定义功能?
  2. Informix IDS 11系统经管(918考试)认证指南,第 5 部分: 数据库做事器行使(5)
  3. 孝敬父母 天经地义 |有人这么疑问?
  4. 如何让自己的网站快速被百度搜索引擎搜索到
  5. java父进程获取子进程异常_如何在perl的父进程中获取死亡的子进程的PID?
  6. 帧同步_什么是帧同步什么是状态同步
  7. 机器人学习--网友资料系列 激光SLAM建图、粒子滤波定位和位姿图优化
  8. SLAM | 三维重建方法之KinectFusion与ElasticFusion详解
  9. 16道嵌入式C语言面试题(转载)
  10. Python + Django 如何支撑了 7 亿月活用户的 Instagram?