理解Golang组件protobuf
什么是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
理解Golang组件protobuf的更多相关文章
- 理解Golang哈希表Map的元素
目录 概述 哈希函数 冲突解决 初始化 结构体 字面量 运行时 操作 访问 写入 扩容 删除 总结 在上一节中我们介绍了 数组和切片的实现原理,这一节会介绍 Golang 中的另一个集合元素 - 哈希 ...
- 深入理解 Vue 组件
深入理解 Vue 组件 组件使用中的细节点 使用 is 属性,解决组件使用中的bug问题 <!DOCTYPE html> <html lang="en"> ...
- 深入理解 Vuejs 组件
本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点.由于本人水平有限,如文中出现错误请多多包涵并指正,感谢.如果需要看更清晰的代码高亮,请跳转至我的个人站点的 深入理解 Vue ...
- 最快的序列化组件protobuf的.net版本protobuf.net
Protobuf是google开源的一个项目,用户数据序列化反序列化,google声称google的数据通信都是用该序列化方法.它比xml格式要少的多,甚至比二进制数据格式也小的多. Prot ...
- 深入理解golang:内存分配原理
一.Linux系统内存 在说明golang内存分配之前,先了解下Linux系统内存相关的基础知识,有助于理解golang内存分配原理. 1.1 虚拟内存技术 在早期内存管理中,如果程序太大,超过了空闲 ...
- 不一样的角度理解Vue组件
什么是组件 以Java.C#等面向对象编程语言的角度去理解Vue组件,能够发现组件和面向对象编程的方式和风格很相似.一切事物皆为对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽 ...
- 尝试用面向对象思维理解Vue组件
什么是组件 用面向对象的思维去理解Vue组件,可以将所有的事物都抽象为对象,而类或者说是组件,都具有属性和操作. 如抽取人类为组件,其基本的属性有姓名.年龄.国籍:基本的方法有吃饭.睡觉.跑步等. & ...
- Golang版protobuf编译
官方网址: https://developers.google.com/protocol-buffers/ (需要FQ) 代码仓库: https://github.com/google/protobu ...
- 如何理解Unity组件化开发模式
Unity的开发模式核心:节点和组件,组件可以加载到任何节点上,每个组件都有 gameobject 属性,可以通过这个属性获取到该节点,即游戏物体. 也就是说游戏物体由节点和组件构成,每个组件表示物体 ...
随机推荐
- Readings
1984 ([英] 乔治·奥威尔) 这书看完我觉得这根本就是一本恐怖小说,当里面的内容正在和将要发生的时候你就不会觉得里面的描述有点搞笑了.不过看到后面有译者的补充内容说和其他国家的朋友讨论的时候, ...
- 用shell脚本新建文件并自动生成头说明信息
目标: 新建文件后,直接给文件写入下图信息 代码实现: [root@localhost test]# vi AutoHead.sh #!/bin/bash #此程序的功能是新建shell文件并自动生成 ...
- linux查看端口号占用命令-netstat
题记 经常会发现,很多时候我们在运行一些带有端口的程序时,程序经常会报端口被占用的问题,比如Tomcat 8080,端口起不来. 查看端口号 netstat 如果发现某个端口被占用后,可以用命令查看, ...
- css 控制li点与文字的距离
ul>li 默认的样式如下 前面的点与文字是有间距的 可见,通过设置 text-indent 属性可以调整li点与文字的距离
- Mybatis分页插件的使用流程
如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件.该插件支持任何复杂的单表.多表分页. 1.引入PageHelper的jar包 在pom.xml中添加如下依赖: 12345 ...
- Hihocoder1456 Rikka with Lattice
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:勇太有一个$n times m$的点阵,他想要从这$n times m$个点中选出三个点 ${A,B,C}$,满足 ...
- 选题在线提交系统(html+JS+php)
前言: 作为学习委员还是有挺多的事情要忙的,比如经常统计同学们的课设题目选择结果.如果老师的要求少一点,我还可以轻松一点.但是当老师对选题有种种限制的时候,自己就估计不会那么好办了.这 ...
- 利用pandas选取某个属性符合指定条件的所有行
最近遇到利用pandas选取指定行的需求,经常忘记,在此做下记录 选取某个属性等于特定值的所有行记录 df[(df[‘column_name’] == target_value)] 注:等于用 '== ...
- Layabox UI 笔记
1.UI List 官方文档是 https://ldc2.layabox.com/doc/?language=zh&nav=zh-js-3-3-7 通常用List的时候会出现滚动条按钮比例拉 ...
- 必备技能二、es6
一.ES6模块 ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量. ES6 的模块化分为导出(export) @与导入(import)两个模块. 特点 ES6 的 ...