Files
rikako-note/protobuf/protobuf.md
2025-02-25 12:41:11 +08:00

74 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [protobuf](#protobuf)
- [language guideproto3](#language-guideproto3)
- [定义message type](#定义message-type)
- [Assign Field Numbers](#assign-field-numbers)
- [重复使用filed number的后果](#重复使用filed-number的后果)
- [指定字段基数](#指定字段基数)
- [Singular](#singular)
- [repeated](#repeated)
- [map](#map)
# protobuf
## language guideproto3
### 定义message type
如下为一个定义search request message format的示例
```proto
synatx="proto3"
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 results_per_page = 3;
}
```
上述示例含义如下:
- `synatx = "proto3"`:
- 代表当前protobuf的language版本为`proto3`
- 如果没有指定`syntax`那么protocol buffer compiler默认会假设在使用`proto2`
- `Search Request`消息定义了3个fields每个field都代表`希望包含在message中的一部分数据`
### Assign Field Numbers
可以为message中的每个field定义一个整数范围为`[1,536,870,911]`,并有如下约束
- message中所有field的给定数字必须唯一
- field number `[19,000, 19,999]`是为`Protocol Buffer`实现保留的如果使用这些数字protocol buffer compiler将会报错
一旦消息类型被使用后field number就不能被改变field number代表message wire format中的field。
如果对field的field number进行了修改代表删除旧的field并且新建一个相同类型的field。
filed number不应该被重用。
对于`频繁被设置`的fields应该将其的field number设置为`[1,15]`。在wire format中field number的值越小占用空间越小。
> 例如,`[1,15]`在编码时只占用1字节而`[16, 2047]`则会占用2字节。
### 重复使用filed number的后果
如果重复使用field number将会造成解码wire-format message的二义性。
> 对于protobuf wire format其在编码和解码过程中`fields的定义`必须一致。
field number被限制为`29bit`故而field number的最大值为`536870911`
### 指定字段基数
在protobuf协议中field可以为如下的集中类型
#### Singular
在proto3中有两种singular field
- `optional`(推荐使用): 一个optional field可能有如下两种状态
- 如果optional field值被设置那么其将会被序列化到`wire`
- 如果optional field值未被设置那么该field将会返回一个默认值并且其不会被序列化到wire中
- `implict`(不推荐使用):一个隐式字段没有显式基数标签,并且行为如下:
- 如果field为一个message type那么其行为和`optional`相同
- 如果field不是message那么其有两种状态
- 如果field被设置为非默认值non-zero其会被序列化到wire中
- 如果field被设置为zero value那么其不会被序列化到wire中
> 相比于`implict`,更推荐使用`optional`,使用`optional`能更好与proto2相兼容
#### repeated
代表该field可以在消息中出现0次或多次消息出现的顺序也将被维护
#### map
代表field为成对的键值对