
在Rust生态中,Serialize和Deserialize trait是数据交换的基石。从JSON解析到二进制协议、从数据库持久化到网络传输,序列化几乎无处不在。但Rust的序列化设计与其他语言有本质区别:它不是通过反射动态分析数据结构,而是通过过程宏在编译时生成高效的序列化代码。
这种设计体现了Rust的哲学——零成本抽象。本文将深入探讨Serialize和Deserialize的设计原理、serde框架的实现机制,以及如何优雅地处理复杂的序列化场景。

// 其他语言的典型实现(伪代码)
interface Serializable {
def serialize() -> String
}
// 每个类型都要实现serialize方法
class User {
def serialize() -> String {
// 手动拼接JSON
return "{\"name\":\"" + this.name + "\",\"age\":" + this.age + "}"
}
}这种方法存在的问题:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct User {
name: String,
age: u32,
}
// 编译器自动生成所有代码!这就是Serde的核心思想:使用过程宏在编译时生成序列化代码。
pub trait Serializer: Sized {
type Ok;
type Error: Error;
// 基础类型
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
// ... 其他基础类型
// 复杂类型
fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
fn serialize_some<T: ?Sized + Serialize>(
self,
value: &T,
) -> Result<Self::Ok, Self::Error>;
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
fn serialize_unit_struct(
self,
name: &'static str,
) -> Result<Self::Ok, Self::Error>;
fn serialize_seq(
self,
len: Option<usize>,
) -> Result<Self::SerializeSeq, Self::Error>;
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error>;
}
// 序列化Map、Vec等集合的辅助trait
pub trait SerializeSeq {
type Ok;
type Error: Error;
fn serialize_element<T: ?Sized + Serialize>(
&mut self,
value: &T,
) -> Result<(), Self::Error>;
fn end(self) -> Result<Self::Ok, Self::Error>;
}这个设计的妙处在于:Serializer trait定义了序列化的"语言",而具体实现(如JSON、YAML、MessagePack)就是对这个"语言"的解释。
// 第一层:数据结构定义
#[derive(Serialize)]
struct User {
name: String,
age: u32,
}
// 第二层:Serialize trait的实现(由derive生成)
impl Serialize for User {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("User", 2)?;
state.serialize_field("name", &self.name)?;
state.serialize_field("age", &self.age)?;
state.end()
}
}
// 第三层:具体序列化器实现(如serde_json)
struct JsonSerializer { /* ... */ }
impl Serializer for JsonSerializer {
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
// 生成 {
Ok(JsonSerializeStruct { /* ... */ })
}
}#[derive(Serialize)]
struct Point {
x: i32,
y: i32,
}
// 编译器生成的伪代码
impl serde::Serialize for Point {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("Point", 2usize)?;
state.serialize_field("x", &self.x)?;
state.serialize_field("y", &self.y)?;
state.end()
}
}use serde::{Serializer, Serializing};
use chrono::{DateTime, Utc};
struct Event {
name: String,
#[serde(serialize_with = "serialize_timestamp")]
timestamp: DateTime<Utc>,
}
// 自定义序列化函数
fn serialize_timestamp<S>(
dt: &DateTime<Utc>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// 将DateTime序列化为Unix时间戳而不是ISO 8601
serializer.serialize_i64(dt.timestamp())
}
// 使用
let event = Event {
name: "test".to_string(),
timestamp: Utc::now(),
};
let json = serde_json::to_string(&event).unwrap();
// 输出类似:{"name":"test","timestamp":1699000000}#[derive(Serialize)]
struct User {
id: u32,
name: String,
// 只在值不为None时序列化
#[serde(skip_serializing_if = "Option::is_none")]
email: Option<String>,
// 完全跳过此字段
#[serde(skip)]
internal_state: String,
// 使用不同的名称
#[serde(rename = "user_age")]
age: u32,
}
// 高级:使用闭包判断是否序列化
fn is_default<T: Default + PartialEq>(value: &T) -> bool {
value == &T::default()
}
#[derive(Serialize)]
struct Config {
#[serde(skip_serializing_if = "is_default")]
debug_mode: bool,
}pub trait Deserializer<'de>: Sized {
type Error: Error;
// 反序列化基础类型
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{ /* ... */ }
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{ /* ... */ }
}
// 访问者trait:定义如何处理不同类型的数据
pub trait Visitor<'de>: Sized {
type Value;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result;
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
where
E: Error,
{ Err(Error::invalid_type(Unexpected::Bool(value), &self)) }
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: Error,
{ Err(Error::invalid_type(Unexpected::Signed(value), &self)) }
fn visit_struct<A>(
self,
len: usize,
visitor: A,
) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{ /* ... */ }
}这个设计使用了访问者模式,好处是:
#[derive(Deserialize)]
struct Point {
x: i32,
y: i32,
}
// 编译器生成的伪代码
impl<'de> serde::Deserialize<'de> for Point {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
enum Field { X, Y }
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Point;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Point")
}
fn visit_map<V>(self, mut map: V) -> Result<Point, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut x = None;
let mut y = None;
while let Some(key) = map.next_key()? {
match key {
Field::X => x = Some(map.next_value()?),
Field::Y => y = Some(map.next_value()?),
}
}
Ok(Point {
x: x.ok_or_else(|| serde::de::Error::missing_field("x"))?,
y: y.ok_or_else(|| serde::de::Error::missing_field("y"))?,
})
}
}
deserializer.deserialize_struct("Point", &["x", "y"], Visitor)
}
}use serde::{Deserializer, Visitor};
use std::fmt;
struct VersionedData {
version: u32,
#[serde(deserialize_with = "deserialize_legacy_format")]
data: String,
}
fn deserialize_legacy_format<'de, D>(
deserializer: D,
) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
struct LegacyVisitor;
impl<'de> Visitor<'de> for LegacyVisitor {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a legacy format string")
}
fn visit_str<E>(self, value: &str) -> Result<String, E>
where
E: serde::de::Error,
{
// 进行格式转换
Ok(value.to_uppercase())
}
}
deserializer.deserialize_str(LegacyVisitor)
}#[derive(Deserialize)]
struct OwnedMessage {
content: String, // 需要分配新内存
}
#[derive(Deserialize)]
struct BorrowedMessage<'a> {
content: &'a str, // 借用原始数据,无分配
}
// 性能对比
fn benchmark() {
let json = r#"{"content":"hello world"}"#;
// 拥有所有权的版本
let owned: OwnedMessage = serde_json::from_str(json).unwrap();
// 借用版本(更快!)
let borrowed: BorrowedMessage = serde_json::from_str(json).unwrap();
}use std::borrow::Cow;
#[derive(Serialize, Deserialize)]
struct SmartData<'a> {
// 如果数据来自JSON字符串,直接借用;否则拥有所有权
text: Cow<'a, str>,
}
// 使用
let json = r#"{"text":"borrowed data"}"#;
let data: SmartData = serde_json::from_str(json).unwrap();
// text 是借用的&str
let owned = SmartData {
text: Cow::Owned("owned data".to_string()),
};
let json = serde_json::to_string(&owned).unwrap();use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Config {
// Option会被序列化为null或对象
timeout: Option<u64>,
// Result不能直接derive,需要自定义
#[serde(serialize_with = "serialize_result")]
status: Result<String, String>,
}
fn serialize_result<S>(
result: &Result<String, String>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match result {
Ok(val) => serializer.serialize_str(val),
Err(err) => serializer.serialize_str(&format!("Error: {}", err)),
}
}
// 测试
let config = Config {
timeout: None,
status: Ok("running".to_string()),
};
let json = serde_json::to_string_pretty(&config).unwrap();
println!("{}", json);use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
#[serde(tag = "type")] // 使用"type"字段作为标签
enum Message {
Text { content: String },
Binary { data: Vec<u8> },
Error { code: u32, message: String },
}
// JSON示例:
// {"type":"Text","content":"hello"}
// {"type":"Binary","data":[1,2,3]}
// {"type":"Error","code":500,"message":"error"}
// 内部标记的替代方案
#[derive(Serialize, Deserialize)]
#[serde(tag = "type", content = "payload")]
enum Message2 {
Text(String),
Binary(Vec<u8>),
}
// JSON:{"type":"Text","payload":"hello"}// 不好:每次都创建新的String
#[derive(Serialize)]
struct User {
name: String,
}
// 更好:对于常见字段使用&str
#[derive(Serialize)]
struct UserRef<'a> {
name: &'a str,
}
// 最佳:使用Cow
#[derive(Serialize)]
struct SmartUser<'a> {
name: Cow<'a, str>,
}use serde_json::Deserializer;
// 不好:一次性加载全部到内存
let data: Vec<User> = serde_json::from_str(large_json)?;
// 更好:流式处理
let stream = Deserializer::from_str(large_json).into_iter::<User>();
for result in stream {
let user: User = result?;
process_user(&user);
}// JSON:易读,但体积大
let json = serde_json::to_string(&data)?;
// MessagePack:紧凑,二进制
let packed = rmp_serde::to_vec(&data)?;
// YAML:可读,但解析慢
let yaml = serde_yaml::to_string(&data)?;
// 性能对比:MessagePack > JSON > YAML (通常)// 问题:Rust使用snake_case,JSON使用camelCase
#[derive(Deserialize)]
struct User {
first_name: String, // 期望 "first_name"
last_name: String,
}
// 解决1:使用rename属性
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct User {
first_name: String, // 现在接受 "firstName"
last_name: String, // 现在接受 "lastName"
}
// 解决2:手动指定
#[derive(Deserialize)]
struct User {
#[serde(rename = "firstName")]
first_name: String,
}#[derive(Deserialize)]
struct Config {
#[serde(default)] // 如果缺失,使用Default::default()
debug: bool,
#[serde(default = "default_timeout")]
timeout: u64,
}
fn default_timeout() -> u64 {
30
}
// 测试
let json = r#"{"debug":true}"#;
let config: Config = serde_json::from_str(json).unwrap();
assert_eq!(config.timeout, 30);#[derive(Deserialize)]
#[serde(deny_unknown_fields)] // 严格模式:未知字段会报错
struct StrictConfig {
name: String,
}
// 默认行为:忽略未知字段
#[derive(Deserialize)]
struct LenientConfig {
name: String,
}
let json = r#"{"name":"test","extra":"field"}"#;
// LenientConfig 反序列化成功
// StrictConfig 会报错use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct ApiResponse<T> {
version: String,
data: T,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum UserData {
V1(UserV1),
V2(UserV2),
}
#[derive(Deserialize)]
struct UserV1 {
name: String,
}
#[derive(Deserialize)]
struct UserV2 {
first_name: String,
last_name: String,
email: String,
}
// 转换函数
impl From<UserData> for User {
fn from(data: UserData) -> Self {
match data {
UserData::V1(v1) => User {
name: v1.name,
email: None,
},
UserData::V2(v2) => User {
name: format!("{} {}", v2.first_name, v2.last_name),
email: Some(v2.email),
},
}
}
}Serialize和Deserialize trait体现了Rust对零成本抽象的执着:
掌握Serialize和Deserialize,你就能:
这是Rust作为系统语言的另一个优势展现——不仅提供性能,还提供了优雅的API设计。🚀