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
字段。