go语言学习-------Go语言中使用 protobuf
来源:互联网 发布:owncloud php fpm 编辑:程序博客网 时间:2024/05/17 06:41
Go语言中使用 protobuf
2016年05月03日
protobuf以前只支持C++, Python和Java等语言, Go语言出来后, 作为亲儿子, 那有不支持的道理呢? github地址: go protobuf.
1. 安装protobuf
<1> 去这儿下载protobuf git clone https://github.com/google/protobuf.git 运行autogen.sh安装获取protobuf编译器protoc编译器,也可以按照下面的步骤安装:
./configuremakemake installprotoc -h<2> 获取并安装proto-gen-go,
go get github.com/golang/protobuf/protoc-gen-go
, 这条命令会生成protoc-gen-go的可执行文件<3> 注意将protoc-gen-go可执行文件路径加到PATH环境变量中, 或者将protoc-gen-go可执行文件放到类似于/usr/local/bin这样的路径下, 只要在PATH路径下就OK. 原因在于, protoc-gen-go可执行文件需要被protoc调用.
<4> 获取 goprotobuf 提供的支持库,包含诸如marshal、unmarshal等功能, 使用命令
go get github.com/golang/protobuf/proto
.<5> 写一个test.proto文件,执行protoc test.proto --go_out=.生成go语言的代码,如果提示libprotoc.so找不到,需要把/usr/local/lib 添加到LD_LIBRARY_PATH环境变量中。
2. 使用protobuf
首先我们需要写一个test.proto文件, 在这个文件中可以定义需要的结构, 例如枚举型, 结构体等等. 那么首先我自己定义了一个结构如下所示,
// test.proto package test; message myMsg { required int32 id = 1; // ID required string str = 2; // str optional int32 opt = 3; //optional field }
注意required是必须要求的字段, optional是可选字段. 同时注意, id=1, 后面的数字仅仅是一个unique标志而已, 保证唯一性就OK!
然后使用protoc test.proto --go_out=. 编译这个文件, 生成的文件名称为test.pb.go文件! 如果这个路径下有多个文件需要编译, 那么执行protoc --go_out=. *.proto就可以. 注意--go_out=后面的参数是生成的文件的路径, 本文生成的文件在'.'当前路径下.
生成的代码如下:
// Code generated by protoc-gen-go.// source: 1.proto// DO NOT EDIT!/*Package test is a generated protocol buffer package.It is generated from these files: 1.protoIt has these top-level messages: MyMsg*/package testimport proto "github.com/golang/protobuf/proto"import math "math"// Reference imports to suppress errors if they are not otherwise used.var _ = proto.Marshalvar _ = math.Inftype MyMsg struct { Id *int32 `protobuf:"varint,1,req,name=id" json:"id,omitempty" bson:"id,omitempty"` Str *string `protobuf:"bytes,2,req,name=str" json:"str,omitempty" bson:"str,omitempty"` Opt *int32 `protobuf:"varint,3,opt,name=opt" json:"opt,omitempty" bson:"opt,omitempty"` XXX_unrecognized []byte `json:"-"`}func (m *MyMsg) Reset() { *m = MyMsg{} }func (m *MyMsg) String() string { return proto.CompactTextString(m) }func (*MyMsg) ProtoMessage() {}func (m *MyMsg) GetId() int32 { if m != nil && m.Id != nil { return *m.Id } return 0}func (m *MyMsg) GetStr() string { if m != nil && m.Str != nil { return *m.Str } return ""}func (m *MyMsg) GetOpt() int32 { if m != nil && m.Opt != nil { return *m.Opt } return 0}func init() {}
特别注意: 生成的文件中的package是test, 那么文件必须放在test文件夹下! 否则会报错: "can't load package: package test: found packages test (test.pb.go) and main (main.go)"
下面写一个测试程序:
// main.gopackage mainimport ( "fmt" t "./test" "github.com/golang/protobuf/proto")func main(){ // 创建一个对象, 并填充字段, 可以使用proto中的类型函数来处理例如Int32(XXX) hw := t.MyMsg{ Id: proto.Int32(1), Str: proto.String("iyviasbjasdv"), Opt: proto.Int32(2), } // 对数据进行编码, 注意参数是message指针 mData, err := proto.Marshal(&hw) if err != nil { fmt.Println("Error1: ", err) return } // 下面进行解码, 注意参数 var umData t.MyMsg err = proto.Unmarshal(mData, &umData) if err != nil { fmt.Println("Error2: ", err) return } // 输出结果 fmt.Println(*umData.Id, " ", *umData.Str, " ", *umData.Opt)}
简单的用法完毕, 然后我们就能愉快地使用protobuf定义自己的消息协议了, 赞!
只有protobuf中的编解码原理, 有时间再去深究了~~~
2. 参考
go protobuf
proto文档
- go语言学习-------Go语言中使用 protobuf
- Go语言中使用 protobuf
- go语言使用protobuf与c++做数据通信。
- go语言学习 1-初识go语言
- Go语言学习3----Go语言特色
- Go语言学习笔记
- go语言学习资源
- GO 语言学习
- go语言学习---map
- go语言学习---错误
- GO语言学习(一)
- GO语言基础学习
- go语言学习1.7
- Go语言学习笔记
- go语言学习网站
- go语言学习
- GO语言学习-并发
- go 语言学习历程
- FrameDecoder API
- java内存详解
- 接口说明文档书写格式
- java 基础增强
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
- go语言学习-------Go语言中使用 protobuf
- 数组
- Unreal 4 Color Offset 色彩偏移
- [LeetCode] 129. Sum Root to Leaf Numbers
- python实现将文件夹下面的不是以py文件结尾的文件都过滤掉
- 利用CUDA和opencv绘制Julia集
- 炫酷时钟(css3+js)
- java基础教程:面向对象之多态(18)
- Lua中含中文字符串长度计算