gogoprotobuf是完全兼容google protobuf,它生成大代码质量确实要比goprotobuf高一些。
一 安装protobuf:
1 下载protobuf源码:
https://github.com/google/protobuf
2 进入源码目录:
./autogen.sh
可能遇到问题:1 该脚本会下载gmock,
若被墙,则需FQ下载并解压为gmock放在该源码目录下
脚本会执行autoreconf命令,ubantu安装:sudo apt-get install autoconf automake libtool )
3 ./configure;make;make check; sudo make install
4 sudo ldconfig # refresh shared library cache
错误及解决方法
protoc: error while loading shared libraries: libprotoc.so.8: cannot open shared
错误原因:
protobuf的默认安装路径是/usr/local/lib,而/usr/local/lib 不在Ubuntu体系默认的 LD_LIBRARY_PATH 里,所以就找不到该lib
解决方法:
输入命令
sudo ldconfig
二 安装gogoprotobuf:
1
go get github.com/gogo/protobuf/proto
2
go get github.com/gogo/protobuf/protoc-gen-gogo
3
go get github.com/gogo/protobuf/gogoproto
4
go get github.com/gogo/protobuf/protoc-gen-gofast
三 使用gogoprotobuf:
1
protoc --gofast_out=. myproto.proto
四
gogoprotobuf的各个option
1 gogoproto.goproto_enum_prefix
选项为false,生成的代码中不加"E_"。
2 gogoproto.goproto_getters
选项为false,不会为message的每个field生成一个Get函数。
3 gogoproto.face
4 gogoproto.nullable
nullable这个option违背protobuf的初衷。使用它,message序列化后,gogo为message的每个field设置一个值,而google protobuf则是要求如果一个option的field没有被赋值,则序列化的时候不会把这个成员序列化进最终结果的。
5 gogoproto.customname
field的名称与message的method的名称一样。
还有gogoproto.customtype
6 gogoproto.marshaler gogoproto.sizer
gogoproto.marshaler_all gogoproto.sizer_all
sizer选项true,gogo会相应的message生成"func Size() int";marshaler为true,gogo为相应的生成:func Marshal()([] byte, int),这个 method会调用Size(),所以marshaler为true的时候,sizer也必须为true。
option (gogoproto.marshaler_all) = true; option (gogoproto.sizer_all) = true;
7 gogoprotobuf.unmarshaler & gogoprotobuf.unmarshaler_all
unmarshaler为true,gogo为相应的message生成func Unmarshal(data []byte) error,代替goprotobuf的proto.Unmarshal([]byte, *struct)函数
option (gogoproto.unmarshaler_all) = true;
例子:
syntax = "proto3";package test;option (gogoproto.gostring_all) = true;option (gogoproto.equal_all) = true;option (gogoproto.verbose_equal_all) = true;// option (gogoproto.goproto_stringer_all) = false;// option (gogoproto.stringer_all) = true;// option (gogoproto.populate_all) = true;// option (gogoproto.testgen_all) = true;// option (gogoproto.benchgen_all) = true;option (gogoproto.marshaler_all) = true;option (gogoproto.sizer_all) = true;option (gogoproto.unmarshaler_all) = true;option (gogoproto.goproto_getters_all) = false;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
编译
#!/bin/sh# proto.sh
编译此 .proto 文件:
protoc
--go_out=. *.proto
每个 Protobuf 消息在 Golang 中有哪一些可用的接口
- 消息中非 repeated 的域都被实现为一个指针,指针为 nil 时表示域未设置
- 消息中 repeated 的域被实现为 slice
- 访问枚举值时,使用“枚举类型名_枚举名”的格式(更多内容可以直接阅读生成的源码)
- 使用 proto.Marshal 函数进行编码,使用 proto.Unmarshal 函数进行解码