Rust 序列化库介绍
概述
序列化是将数据结构或对象转换为可存储或传输格式的过程,反序列化则是其逆过程。Rust 生态系统中有多个优秀的序列化库,本文将详细介绍主流的序列化库及其使用方法。
主流序列化库对比
| 库名 | 格式支持 | 性能 | 生态系统 | 特点 |
|---|---|---|---|---|
| Serde | JSON, YAML, TOML, XML 等 | 高 | 最丰富 | 事实标准,零成本抽象 |
| bincode | 二进制 | 极高 | 好 | 紧凑的二进制格式 |
| rmp-serde | MessagePack | 高 | 中等 | 高效的二进制 JSON |
| postcard | 自定义二进制 | 极高 | 中等 | 无标准库,嵌入式友好 |
| ciborium | CBOR | 高 | 中等 | RFC 7049 标准 |
Serde - Rust 序列化框架
1. 基础介绍
Serde 是 Rust 中最流行的序列化框架,提供了零成本抽象的序列化和反序列化功能。
添加依赖
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" # JSON 支持
serde_yaml = "0.9" # YAML 支持
toml = "0.8" # TOML 支持
2. 基础用法
简单结构体序列化
use serde::{
Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct User {
id: u32,
name: String,
email: String,
active: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let user = User {
id: 1,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
active: true,
};
// 序列化为 JSON
let json = serde_json::to_string(&user)?;
println!("JSON: {}", json);
// 从 JSON 反序列化
let user_from_json: User = serde_json::from_str(&json)?;
println!("User: {:?}", user_from_json);
Ok(())
}
复杂数据结构
use serde::{
Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug)]
struct Product {
id: u32,
name: String,
price: f64,
tags: Vec<String>,
metadata: HashMap<String, String>,
category: Category,
}
#[derive(Serialize, Deserialize, Debug)]
struct Category {
id: u32,
name: String,
parent_id: Option<u32>,
}
fn complex_serialization_example() -> Result<(), Box<dyn std::error::Error>> {
let mut metadata = HashMap::new();
metadata.insert("color".to_string(), "red".to_string());
metadata.insert("size".to_string(), "large".to_string());
let product = Product {
id: 101,
name: "Gaming Laptop".to_string(),
price: 1299.99,
tags: vec!["electronics".to_string(), "gaming".to_string()],
metadata,
category: Category {
id: 1,
name: "Computers".to_string(),
parent_id: None,
},
};
// 美化输出的 JSON
let json = serde_json::to_string_pretty(&product)?;
println!("{}", json);
Ok(())
}
3. Serde 属性和自定义
字段重命名和跳过
use serde::{
Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct ApiResponse {
#[serde(rename = "user_id")]
id: u32,
#[serde(rename = "full_name")]
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
avatar_url: Option<String>,
#[serde(skip)]
internal_data: String,
#[serde(default)]
is_verified: bool,
}
fn attributes_example() -> Result<(), Box<dyn std::error::Error>> {
let response = ApiResponse {
id: 123,
name: "John Doe".to_string(),
avatar_url: None,
internal_data: "secret".to_string(),
is_verified: true,
};
let json = serde_json::to_string_pretty(&response)?;
println!("{}", json);
// 输出不包含 internal_data 和 avatar_url (因为是 None)
Ok(())
}
自定义序列化函数
use serde::{
Deserialize, Serialize, Serializer, Deserializer};
use chrono::{
DateTime, Utc, TimeZone};
#[derive(Serialize, Deserialize, Debug)]
struct Event {
name: String,
#[serde(
serialize_with = "serialize_datetime",
deserialize_with = "deserialize_datetime"
)]
created_at: DateTime<Utc>,
}
fn serialize_datetime<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let timestamp = dt.timestamp();
serializer.serialize_i64(timestamp)
}
fn deserialize_datetime<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let timestamp = i64::deserialize(deserializer)?;
Ok(Utc.timestamp_opt(timestamp, 0).unwrap())
}
4. 枚举序列化
use serde::{
Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type")]
enum Message {
#[serde(rename = "text")]
Text {
content: String },
#[serde(rename = "image")]
Image {
url: String, caption: Option<String> },
#[serde(rename = "file")]
File {
filename: String, size: u64 },
}
#[derive(Serialize, Deserialize, Debug)]
enum Status {
Pending,
#[serde(rename = "in_progress")]
InProgress,
Completed,
Failed(String),
}
fn enum_serialization_example() -> Result<(), Box<dyn std::error::Error>> {
let messages = vec![
Message::Text {
content: "Hello, world!".to_string(),
},
Message::Image {
url: "https://example.com/image.jpg".to_string(),
caption: Some("A beautiful sunset".to_string()),
},
Message::File {
filename: "document.pdf".to_string(),
size: 1024768,
},
];
for message in &messages {
let json = serde_json::to_string_pretty(message)?;
println!("{}\n", json);
}
let status = Status::Failed("Network timeout".to_string());
let status_json = serde_json::to_string(&status)?;
println!("Status: {}", status_json);
Ok(())
}
二进制序列化库
1. bincode
高性能的二进制序列化库,特别适合需要紧凑存储的场景。
[dependencies]
bincode = "1.3"
serde = { version = "1.0", features = ["derive"] }
use serde::{
Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct GameState {
player_id: u32,
position: (f32, f32, f32),
health: u8,
inventory: Vec<String>,
level: u16,
}
fn bincode_example() -> Result<(), Box<dyn std::error::Error>> {
let game_state = GameState {
player_id: 12345,
position: (100.5, 200.0, 50.25),
health: 85,
inventory: vec![
"sword".to_string(),
"health_potion".to_string(),
"key".to_string(),
],
level: 42,
};
// 序列化为二进制
let encoded = bincode::serialize(&game_state)?;
println!("二进制大小: {} bytes", encoded.len());
// 反序列化
let decoded: GameState = bincode::deserialize(&encoded)?;
println!("反序列化结果: {:?}", decoded);
assert_eq!(game_state, decoded);
// 与 JSON 大小比较
let json_size = serde_json::to_string(&game_state)?.len();
println!("JSON 大小: {} bytes", json_size);
println!("压缩比: {:.1}%", (encoded.len() as f64 / json_size as f64) * 100.0);
Ok(())
}
2. MessagePack (rmp-serde)
高效的二进制 JSON 格式。
[dependencies]
rmp-serde = "1.1"
serde = { version = "1.0", features = ["derive"] }
use serde::{
Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct ApiData {
users: Vec<User>,
total_count: u32,
page: u32,
}
#[derive(Serialize, Deserialize, Debug)]
struct User {
id: u32,
username: String,
email: String,
created_at: i64,
}
fn messagepack_example() -> Result<(), Box<dyn std::error::Error>> {
let data = ApiData {
users: vec![
User {
id: 1,
username: "alice".to_string(),
email: "alice@example.com".to_string(),
created_at: 1640995200,
},
User {
id: 2,
username: "bob".to_string(),
email: "bob@example.com".to_string(),
created_at: 1640995300,
},
],
total_count: 2,
page: 1,
};
// 序列化为 MessagePack
let packed = rmp_serde::to_vec(&data)?;
println!("MessagePack 大小: {} bytes", packed.len());
// 反序列化
let unpacked: ApiData = rmp_serde::from_slice(&packed)?;
println!("用户数量: {}", unpacked.users.len());
// 大小比较
let json_size = serde_json::to_string(&data)?.len();
println!("JSON 大小: {} bytes", json_size);
Ok(())
}
性能比较示例
use serde::{
Deserialize, Serialize};
use std::time::Instant;
#[derive(Serialize, Deserialize, Debug, Clone)]
struct BenchmarkData {
numbers: Vec<i32>,
strings: Vec<String>,
neste

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



