Protobuf 文件语法
Protobuf 文件的具体语法
1. 基本语法
1.1 语法版本
使用 syntax
指定 Protobuf 的版本(proto2
或 proto3
),目前推荐使用 proto3
。
syntax = "proto3";
1.2 包声明
使用 package
定义命名空间,避免不同模块间的命名冲突。
package mypackage;
1.3 导入其他文件
可以通过 import
导入其他 .proto
文件中的定义。
import "common.proto";
2. 数据类型
2.1 标量类型
Protobuf 支持多种标量类型:
数据类型 | 说明 | 示例 |
---|---|---|
int32 / int64 |
整数,32位或64位 | int32 age = 1; |
uint32 / uint64 |
无符号整数,32位或64位 | uint32 id = 2; |
float |
单精度浮点数 | float score = 3; |
double |
双精度浮点数 | double ratio = 4; |
bool |
布尔值 | bool is_active = 5; |
string |
字符串 | string name = 6; |
bytes |
二进制数据 | bytes data = 7; |
2.2 复合类型
- 枚举类型:用于定义一组命名常量。
- 消息类型:类似于结构体,用于定义复杂的数据结构。
3. 消息定义
3.1 基本结构
消息是 Protobuf 的核心,用于定义数据结构。
message User {
int32 id = 1; // 用户ID
string name = 2; // 用户名
bool is_active = 3; // 是否活跃
}
3.2 可选字段
在 proto3
中,所有字段默认是可选的,无需显式标记。
3.3 嵌套消息
消息可以包含其他消息作为字段。
message Address {
string street = 1;
string city = 2;
}
message User {
int32 id = 1;
string name = 2;
Address address = 3; // 嵌套消息
}
3.4 枚举类型
用于定义一组枚举值。
enum UserType {
UNKNOWN = 0;
ADMIN = 1;
USER = 2;
}
message User {
int32 id = 1;
string name = 2;
UserType type = 3; // 使用枚举类型
}
3.5 重复字段
使用 repeated
定义列表字段。
message User {
int32 id = 1;
repeated string roles = 2; // 角色列表
}
4. 服务定义
4.1 服务结构
用于定义 RPC 服务的接口。
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
rpc ListUsers (Empty) returns (stream User);
}
4. 字段编号
每个字段需要分配一个唯一的编号,用于二进制编码时的标识。
message User {
int32 id = 1; // 字段编号从1开始
string name = 2; // 每个字段编号必须唯一
}
- 字段编号的范围为 1 ~ 2^29 - 1。
- 编号范围:
- 1~15:适合频繁出现的小字段(编码紧凑)。
- 16~2^29 - 1:一般字段。
---
### **5. 注释**
- 使用 `//` 添加单行注释。
- 使用 `/* */` 添加多行注释。
```proto
message User {
int32 id = 1; // 用户ID
/* 用户名 */
string name = 2;
}
8. Protobuf 文件示例
完整示例:
syntax = "proto3";
package example;
import "google/protobuf/empty.proto";
enum UserType {
UNKNOWN = 0;
ADMIN = 1;
USER = 2;
}
message User {
int32 id = 1;
string name = 2;
UserType type = 3;
repeated string roles = 4; // 用户角色
}
message UserRequest {
int32 id = 1;
}
message UserResponse {
User user = 1;
}
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
rpc ListUsers (google.protobuf.Empty) returns (stream User);
}
总结
- Protobuf 文件以
.proto
为扩展名,定义了数据结构和 RPC 服务接口。 - 通过
protoc
工具,可以根据.proto
文件生成多种语言的代码。 - 语法简单,支持多种类型和扩展性,适合分布式系统和微服务开发场景。