在go中使用 Google  protobuf,有两个可选用的包goprotobuf(go官方出品)和gogoprotobuf。
 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
 选项为true的时候,为message生成相应的 interface

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 函数进行解码


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐