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; // 用户IDstring 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
文件生成多种语言的代码。 - 语法简单,支持多种类型和扩展性,适合分布式系统和微服务开发场景。