serde #
1cargo add serde --features derive
Serde 是一个高效且通用的框架,用于序列化和反序列化 Rust 数据结构。
Serde生态系统包含了两部分:一是知道如何序列化和反序列化自身的数据结构,二是知道如何序列化和反序列化其他内容的数据格式。Serde 提供了这两组之间交互的层,使得任何支持的数据结构都可以使用任何支持的数据格式进行序列化和反序列化。
- 数据结构:指的是 Rust 中的结构体或枚举等类型,它们可以通过 Serde 自动实现序列化和反序列化功能。这意味着这些数据结构知道如何将自己转换为某种序列化格式(如 JSON、YAML)或者从这些格式中恢复自身。
- 数据格式:指的是各种数据存储或传输的格式,如 JSON、YAML、MessagePack 等。它们定义了如何将数据以某种标准进行编码和解码。
设计 #
很多其他编程语言依赖运行时反射来序列化数据,而Serde则构建在Rust强大的trait系统之上。一个知道如何序列化和反序列化自身的数据结构,就是实现了 Serde 的 Serialize
和 Deserialize
trait的结构(或者使用Serde的derive性在编译时自动生成实现)。这避免了任何反射或运行时类型信息的开销。实际上,在许多情况下,数据结构和数据格式之间的交互可以被Rust编译器完全优化掉,使得Serde序列化能够达到与针对特定数据结构和数据格式手写的序列化器相同的速度。
数据格式(Data formats) #
以下是社区为 Serde 实现的部分数据格式列表:
- JSON,被许多 HTTP API 使用的无处不在的 JavaScript 对象表示法。
- Postcard,一种适用于 no_std 和嵌入式系统的紧凑二进制格式。
- CBOR,一种无需版本协商的简明二进制对象表示格式,设计用于小型消息。
- YAML,一个自称人性化的配置语言,而不是标记语言。
- MessagePack,一种类似于紧凑型 JSON 的高效二进制格式。
- TOML,Cargo 使用的最小配置格式。
- Pickle,Python 世界常用的格式。
- RON,Rust 风格的对象表示法。
- BSON,MongoDB 使用的数据存储和网络传输格式。
- Avro,Apache Hadoop 中使用的二进制格式,支持架构定义。
- JSON5,JSON 的超集,包含一些 ES5 的特性。
- URL查询字符串,采用 x-www-form-urlencoded 格式。
- Starlark,Bazel 和 Buck 构建系统用于描述构建目标的格式。(仅序列化)
- Envy,一种将环境变量反序列化为 Rust 结构体的方式。(仅反序列化)
- Envy Store,一种将 AWS 参数存储参数反序列化为 Rust 结构体的方式。(仅反序列化)
- S-expressions,Lisp 语言家族使用的代码和数据的文本表示。
- D-Bus 的二进制线格式。
- FlexBuffers,Google 的 FlatBuffers 零拷贝序列化格式的无模式表亲。
- Bencode,BitTorrent 协议使用的简单二进制格式。
- Token 流,用于处理 Rust 过程宏输入。(仅反序列化)
- DynamoDB Items,rusoto_dynamodb 用于与 DynamoDB 传输数据的格式。
- Hjson,为人类阅读和编辑设计的 JSON 语法扩展。(仅反序列化)
- CSV,逗号分隔值是一种表格文本文件格式。
数据结构 #
开箱即用的情况下,Serde 能够在上述任何格式中序列化和反序列化常见的 Rust 数据类型。例如 String
、&str
、usize
、Vec<T>
、HashMap<K,V>
都是支持的。此外,Serde 提供了一个derive宏来为程序中的结构体生成序列化实现。使用derive宏的方式如下:
1
2use serde::{Serialize, Deserialize};
3
4#[derive(Serialize, Deserialize, Debug)]
5struct Point {
6 x: i32,
7 y: i32,
8}
9
10fn main() {
11 let point = Point { x: 1, y: 2 };
12
13 // Convert the Point to a JSON string.
14 let serialized = serde_json::to_string(&point).unwrap();
15
16 // Prints serialized = {"x":1,"y":2}
17 println!("serialized = {}", serialized);
18
19 // Convert the JSON string back to a Point.
20 let deserialized: Point = serde_json::from_str(&serialized).unwrap();
21
22 // Prints deserialized = Point { x: 1, y: 2 }
23 println!("deserialized = {:?}", deserialized);
24}