Go语言中使用protobuf开发者指南

protobuf是什么?

官方给出的定义是:Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

翻译:是Google的语言中立、平台中立、可扩展的机制,用于序列化结构化数据,比如XML,但是更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码轻松地在各种数据流和各种语言之间写入和读取结构化数据。

优点:

  • 支持多语言。(go,C++,Java等多种语言)
  • 简单高效

具体可参考:protobuf官网

1.安装protobuf

github下载地址:https://github.com/golang/protobuf/releases

2.安装protoc-gen-go

非常简单只需要在go module运行一下以下命令

go get -u github.com/golang/protobuf/protoc-gen-go

3.1.定义protobuf

需要创建后缀为.proto的文件。

syntax = "proto3";
package test;
option go_package = "./;test";
message Request {
  string query = 1;
  int32 page = 2;
  int32 size = 3;
}
  • proto3: 为版本号,如果不定义会默认使用proto2版本,syntax = "proto3";必须放在第一行
  • message: 消息定义,每个字段都有名称,类型和编号,注意:每个字段都有一个唯一的编号,指定的最小字段号是1,最大字段号是2^29-1或536870911。不能使用数字19000到19999。
  • package: 声明所在包
  • go_package: Go包的完整导入路径中声明文件所属的包

3.2.消息类型

.proto 的类型 Go 的类型
double float64
float float32
int32 int32
int64 int64
uint32 uint32
uint64 uint64
sint32 int32
sint64 int64
fixed32 uint32
fixed64 uint64
sfixed32 int32
sfixed64 int64
bool bool
string string
bytes []byte

3.3.枚举类型

必须有一个零值作为其第一个元素;

enum Week {
    Sunday=0;
    Monday=1;
    Tuesday=2;
}

3.4.切片类型

只需要在消息类型的元素类型前面加repeated,编译时会默认转成go切片类型。

message Request {
  repeated string query = 1;  // 切片类型
  int32 page = 2;
  int32 size = 3;
}

3.5.嵌套类型

在消息类型内,是可以定义一个消息类型。 `condition`消息属于了`SearchRequest`的内部消息:
message Request {
    message Condition {
        string username = 1;
        string password = 2;
    }
    int32 page = 2;
    int32 size = 3;
}

当然也可以使用在消息类型外定义的消息类型,这样就可以使得消息类型得到重用效果

message Condition {
    string username = 1;
    string password = 2;
}
message Request {
    Condition condition = 1; // 引入消息类型
    int32 page = 2;
    int32 size = 3;
}

3.6.map类型

定义map类型,protobuf也是提供了非常方便的方式。


map<key_type, value_type> map_field = N; // map的定义

message Request {
  map<string, string> query = 1; // 定义一个字符串键和值的map类型
}

需要注意的是:

  • map类型不能在使用repeated
  • 如果为映射字段提供键但没有值,则序列化字段时的行为取决于语言。在C ++,Java和Python中,类型的默认值是序列化的,而在其他语言中,则没有序列化的值。

4.服务定义

如果你使用RPC作为微服务开发,那么你就可以在.proto文件中定义RPC服务接口:

service UserService {
  rpc Search(Request) returns (Response);
}
  • UserService: 你定义的服务接口名称;
  • Search: 你定义的服务接口方法名称;
  • Request: 服务方法传参信息;
  • Response: 服务响应结果信息。

编译

切换到.proto的文件目录下,执行:

protoc --go_out=. *.proto
  • –go_out: 生成Go代码DST_DIR
  • *.proto: proto文件路径

猜你喜欢

转载自blog.csdn.net/Xiao_W_u/article/details/115318154