serde
前言
序列化和反序列化是非常通用的功能血崭,在網(wǎng)絡(luò)傳輸,數(shù)據(jù)存儲上極其常見的夹纫。序列化和反序列化的通用解釋是:
seriallization 序列化 : 將對象轉(zhuǎn)化為便于傳輸?shù)母袷剑?常見的序列化格式:二進(jìn)制格式舰讹,字節(jié)數(shù)組,json字符串月匣,xml字符串。
deseriallization 反序列化:將序列化的數(shù)據(jù)恢復(fù)為對象的過程素标。
介紹
Serde
是高效通用的對Rust數(shù)據(jù)結(jié)構(gòu)進(jìn)行序列化和反序列化的框架院刁。
Serde
生態(tài)系統(tǒng)由知道如何序列化和反序列化自身的數(shù)據(jù)結(jié)構(gòu),以及知道如何序列化和反序列化其他事物的數(shù)據(jù)格式退腥。
Serde
允許使用任何支持序列化和反序列化的基礎(chǔ)數(shù)據(jù)類型組成的復(fù)雜數(shù)據(jù)結(jié)構(gòu)狡刘。
基礎(chǔ)類型
開箱即用, Serde
支持序列化Rust的所有基礎(chǔ)類型嗅蔬,例如String
, &str
, usize
, Vec<T>
, HashMap<K,V>
,這些都支持艺蝴。
數(shù)據(jù)格式
以下是社區(qū)為Serde實(shí)現(xiàn)的部分?jǐn)?shù)據(jù)格式鸟废,例如JSON, Bincode, MessagePack, CBOR, YAML, TOML, RON, BSON, JSON5, URL
使用
基于派生宏
首先在Cargo.toml中添加
...
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.0"
...
然后在src/main.rs
定義Person
結(jié)構(gòu),并實(shí)現(xiàn)#[derive(Serialize, Deserialize)]
缩擂。
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
weight: Option<u8>,
}
fn main() {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// 解析字符串到Person對象。
let p: Person = serde_json::from_str(data).unwrap();
println!("Please call {} at the number {}", p.name, p.phones[0]);
// Person對象轉(zhuǎn)為JSON字符串.
let serialized = serde_json::to_string(&p).unwrap();
println!("serialized = {}", serialized);
}
輸出
Running `target\debug\examples\u-serde.exe`
Please call John Doe at the number +44 1234567
serialized = {"name":"John Doe","age":43,"phones":["+44 1234567","+44 2345678"],"weight":null}
在結(jié)構(gòu)中懈费,我們也可以定義Option
類型作為可以缺省字段博脑,不影響反序列化。
但如果我們把age
字段在刪除了寨闹,那么程序運(yùn)行時會如下錯誤:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `age`", line: 8, column: 9)'
其他
上述例子是轉(zhuǎn)化為JSON
格式的君账,如果想轉(zhuǎn)化為YAML
格式的,不需要修改結(jié)構(gòu)體乡数,只需在Cargo.toml
中引入serde_yaml = "0.8"
包。
然后在先前代碼后添加如下代碼:
let config = serde_yaml::to_string(&p).unwrap();
println!("config = {}", config);
輸出
config = ---
name: John Doe
age: 43
phones:
- +44 1234567
- +44 234
疑問
- 能否支持枚舉類型绳矩?
- 能否支持字段的默認(rèn)值玖翅?
- 能否忽略某個字段?
- 能否支持字段改名应媚?
- 能否自定義序列化猜极?
可以統(tǒng)統(tǒng)可以,上述問題答案都可以在社區(qū)例子中找到答案跟伏。