Protocol Buffers(简称protobuf)是一种轻量级、高效的数据交换格式,由Google开发,用于结构化数据序列化,类似于XML或JSON,但更加高效、更小、更快。它们旨在用于通信协议、数据存储等领域,适用于各种语言。
协议定义
Protocol Buffers 通过一种简单的语言来定义数据结构,然后使用特定的编译器将这些定义转换为不同编程语言的类文件。这些类文件包含用于序列化和反序列化数据的代码,以及数据结构的访问方法。
语法要点
Protocol Buffers 的语法主要包含以下要点:
-
消息定义(Message Definition):使用 message 关键字定义消息,类似于类的定义。每个消息包含一个或多个字段。
message Person { required int32 id = 1; required string name = 2; optional string email = 3; }
-
字段类型(Field Types):字段可以具有多种数据类型,包括基本数据类型(如整数、浮点数、布尔值、字符串等)以及其他消息类型。
-
字段修饰符(Field Modifiers):字段可以标记为 required(必需)、optional(可选)或 repeated(重复)。
- required:字段必须在消息中存在且不为空。
- optional:字段可以存在,也可以为空。
- repeated:字段可以重复出现,相当于数组或列表。
-
字段标识号(Field IDs):每个字段都有一个唯一的标识号,用于在消息中标识字段。这些标识号应该是正整数,并且在消息中必须是唯一的。
标识号范围是 1 到 536870911(2^29 - 1),其中 1 到 15 用于更小的消息大小。
保留了标识号 19000 到 19999 用于特殊目的。 -
默认值(Default Values):可以为字段指定默认值,在字段没有被设置时将使用该默认值。
message Person { required int32 id = 1; required string name = 2; optional string email = 3 [default = ""]; }
示例
下面是一个简单的示例,展示了如何使用 Protocol Buffers 定义一个消息并进行序列化和反序列化:syntax = "proto3"; message Person { int32 id = 1; string name = 2; repeated string emails = 3; }
然后,通过 Protocol Buffers 提供的编译器将该定义文件编译成目标语言的类文件,以便在应用程序中使用。
数据类型
Protocol Buffers 支持多种字段类型,这些类型用于定义消息中的各种数据。下面是 Protocol Buffers 中常用的字段类型:
基本数据类型(Scalar Types):
double:双精度浮点数(64位)。
float:单精度浮点数(32位)。
int32:有符号 32 位整数。Varint 编码。
int64:有符号 64 位整数。Varint 编码。
uint32:无符号 32 位整数。Varint 编码。
uint64:无符号 64 位整数。Varint 编码。
sint32:有符号 32 位整数,使用 ZigZag 编码。
sint64:有符号 64 位整数,使用 ZigZag 编码。
fixed32:固定 32 位整数。固定 4 个字节。
fixed64:固定 64 位整数。固定 8 个字节。
sfixed32:有符号固定 32 位整数。固定 4 个字节。
sfixed64:有符号固定 64 位整数。固定 8 个字节。
bool:布尔值,只能是 true 或 false。
string:字符串。
bytes:原始字节序列。
复合类型(Composite Types):
message:其他消息类型。
enum:枚举类型。
特殊类型(Special Types):
Any:表示任意消息类型。
Duration:表示时间段。
Timestamp:表示时间戳。
FieldMask:用于指定要更新的消息字段。
Struct:表示任意结构化数据。
集合类型(Collections Types):
repeated:用于表示数组或列表,可以包含零个或多个元素。
安装protocol buffers
下载安装包
wget https://github.com/protocolbuffers/protobuf/releases/download/v26.0/protobuf-26.0.tar.gz
解压
tar -zxvf protobuf-26.0.tar.gz
测试安装结果
protoc --version
生成一个看看
编写一份以.proto为扩展名的文件response.proto
syntax = "proto3";
option go_package = "./;proto";
// 定义数据结构,message 你可以想象成java的class,c语言中的struct
message Response {
string data = 1; // 定义一个string类型的字段,字段名字为data, 序号为1
int32 status = 2; // 定义一个int32类型的字段,字段名字为status, 序号为2
}
生成golang的代码,需要安装插件
go install github.com/golang/protobuf/protoc-gen-go@latest
执行代码:
protoc --go_out=. response.proto
其中--go_out代表输出golang代码,protoc 还支持其他语言类型,如PHP、JAVA 等
--cpp_out=OUT_DIR 指定代码生成目录,生成 C++ 代码
--csharp_out=OUT_DIR 指定代码生成目录,生成 C# 代码
--java_out=OUT_DIR 指定代码生成目录,生成 java 代码
--js_out=OUT_DIR 指定代码生成目录,生成 javascript 代码
--objc_out=OUT_DIR 指定代码生成目录,生成 Objective C 代码
--php_out=OUT_DIR 指定代码生成目录,生成 php 代码
--python_out=OUT_DIR 指定代码生成目录,生成 python 代码
--ruby_out=OUT_DIR 指定代码生成目录,生成 ruby 代码
就会生成一份名为 response.pb.go的文件