Rust Serde 与序列化
Serde 作为序列化框架:derive、格式无关的数据模型、JSON 常见边界。
#concept
#growing
#dev
#rust
[!info] related notes
Rust Serde 与序列化
这个概念为什么出现
服务要在 JSON/消息/配置间搬结构体。
Serde 用 Serialize/Deserialize 把数据模型与格式解耦。
[!abstract] 一句话理解 为类型 derive Serde trait,再选用
serde_json等格式 crate 做编码解码;属性控制字段命名与默认值。
最小可运行示例
场景:API 响应结构体
先在 Cargo 项目中添加依赖:
cargo add serde --features derive
cargo add serde_json
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
struct OrderDto {
id: u64,
#[serde(rename = "total_cents")]
total: u32,
}
fn main() -> Result<(), serde_json::Error> {
let order = OrderDto { id: 1, total: 990 };
let json = serde_json::to_string(&order)?;
println!("{json}");
let back: OrderDto = serde_json::from_str(&json)?;
assert_eq!(back, order);
Ok(())
}
运行 cargo run 输出 {"id":1,"total_cents":990},并实际完成反序列化与值相等断言。
结合场景再看三个关注点
- DTO 与领域模型可分离
- 未知字段策略(deny_unknown_fields)
- 错误是 Result
核心概念
- 格式无关的数据模型与 Serializer/Deserializer trait,不要求所有格式先分配一棵中间 JSON 树
- 属性:
rename、default、skip、flatten - 枚举外部/内部标记
- 自定义 impl 或字段转换处理特殊格式;derive 只生成编码解码,不自动验证业务不变量
- JSON 默认通常忽略未知 struct 字段;此例显式 deny_unknown_fields,新增字段会被拒绝,需考虑兼容性
- 缺少必需字段与数值越界会报错;default 为缺失字段提供默认,不能普遍把 null 当缺失
- Rust u64 可以表示的整数可能超出 JavaScript Number 的安全范围,跨语言 ID 必要时采用字符串契约
工程实践
- 公共 API 版本化字段
- 测试黄金 JSON
- 大数/金额用整数
- 流式 API 处理大文档
本节总结
- Serde 是生态中枢
- derive 覆盖大多数
- 与 HTTP/配置强相关
自测题
- 为什么金额别用 f64 进 JSON DTO?
- Serialize 与具体 JSON 库关系?
参考答案
- 浮点精度。
- Serde 定义如何序列化;serde_json 提供 JSON 格式实现。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| serde.rs | 官方生态 | 框架 |
| serde_json | 生态 | JSON |