proto(Protocol Buffers,简称 Protobuf)是 Google 开发的一种轻量级、高效的数据序列化格式,用于结构化数据的存储和传输。在 Protobuf 中,数据通过 .proto 文件定义,文件中包含消息类型(message types)和字段类型(field types)。
以下是 Protobuf 中支持的基本数据类型(标量类型,scalar types)的详细介绍:
Protobuf 的基本数据类型
| 类型 | 说明 | 对应 Go 的类型 |
|---|---|---|
double |
双精度浮点数,64 位浮点数 | float64 |
float |
单精度浮点数,32 位浮点数 | float32 |
int32 |
带符号的 32 位整数,变长编码(Varint)。适用于非负值较小的整数。 | int32 |
int64 |
带符号的 64 位整数,变长编码(Varint)。适用于非负值较大的整数。 | int64 |
uint32 |
无符号的 32 位整数,变长编码(Varint)。 | uint32 |
uint64 |
无符号的 64 位整数,变长编码(Varint)。 | uint64 |
sint32 |
带符号的 32 位整数,使用 ZigZag 编码的 Varint。适用于负值较多的场景。 | int32 |
sint64 |
带符号的 64 位整数,使用 ZigZag 编码的 Varint。适用于负值较多的场景。 | int64 |
fixed32 |
无符号的 32 位整数,固定长度编码。适用于值较大的整数。 | uint32 |
fixed64 |
无符号的 64 位整数,固定长度编码。适用于值较大的整数。 | uint64 |
sfixed32 |
带符号的 32 位整数,固定长度编码。 | int32 |
sfixed64 |
带符号的 64 位整数,固定长度编码。 | int64 |
bool |
布尔值,true 或 false |
bool |
string |
UTF-8 编码的字符串,长度不能超过 2^32。 |
string |
bytes |
任意二进制数据,长度不能超过 2^32。 |
[]byte |
选择合适的数据类型
-
整数类型:
- 如果字段的值可能为负数,使用
int32或int64。 - 如果字段的值始终为非负数,使用
uint32或uint64。 - 对于可能包含负数的字段,如果负值较多,推荐使用
sint32或sint64,因为它们使用 ZigZag 编码,能更高效地处理负数。 - 对于值较大的整数,推荐使用
fixed32或fixed64,因为它们的编码长度固定,能够避免 Varint 编码的开销。
- 如果字段的值可能为负数,使用
-
浮点数类型:
- 对于需要高精度的浮点数,使用
double。 - 对于需要较少存储空间的浮点数,使用
float。
- 对于需要高精度的浮点数,使用
-
布尔类型:
- 用于表示
true或false。
- 用于表示
-
字符串和二进制数据:
- 使用
string表示文本数据。 - 使用
bytes表示二进制数据。
- 使用
示例 .proto 文件
syntax = "proto3";
package example;
message Person {
string name = 1; // 字符串
int32 age = 2; // 32 位整数
double height = 3; // 双精度浮点数
bool is_student = 4; // 布尔值
repeated string hobbies = 5; // 字符串列表
bytes avatar = 6; // 二进制数据
}
注意事项
-
默认值:
- 如果字段未设置值,Protobuf 会使用默认值:
- 数值类型:
0 - 布尔类型:
false - 字符串类型:空字符串
"" - 二进制类型:空字节数组
[]byte{} - 枚举类型:第一个枚举值(默认值为
0)
- 数值类型:
- 如果字段未设置值,Protobuf 会使用默认值:
-
字段编号:
- 每个字段必须有一个唯一的编号(从
1开始)。 - 字段编号用于标识字段,范围是
1到2^29 - 1,其中19000到19999是保留值。
- 每个字段必须有一个唯一的编号(从
-
字段规则:
optional:字段是可选的(默认行为)。required:字段是必需的(不推荐使用,已被废弃)。repeated:字段是一个列表。
-
proto3和proto2的区别:proto3是当前推荐使用的版本,简化了语法并移除了required字段。