自定义序列化
字段属性
自定义序列化 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。
自定义 serde
serde 可以通过属性精细控制字段如何映射到某种格式。您可以重命名字段、跳过字段、设置默认值等,全部通过 #[serde(...)] 完成。
重命名字段
使用 rename 将 Rust 字段名映射为输出中的其他键名,这在 JSON 使用不同命名约定时非常有用。
use serde::Serialize;
#[derive(Serialize)]
struct User {
#[serde(rename = "userName")]
user_name: String,
}重命名所有字段
使用 rename_all 一次性为所有字段应用命名约定,例如将 Rust 的 snake_case 转换为 JSON 的 camelCase。
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct User {
first_name: String,
last_name: String,
}跳过字段
skip 会完全省略某个字段。skip_serializing_if 会根据条件省略字段,例如隐藏空的选项值。
use serde::Serialize;
#[derive(Serialize)]
struct User {
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
nickname: Option<String>,
}反序列化时使用默认值
当输入中缺少字段时,default 会提供一个值,从而避免反序列化失败。
use serde::Deserialize;
#[derive(Deserialize)]
struct Config {
#[serde(default)]
retries: u32,
}自定义默认函数
将 default 指向一个函数,即可提供非零的备用值。
use serde::Deserialize;
fn default_port() -> u16 { 8080 }
#[derive(Deserialize)]
struct Config {
#[serde(default = "default_port")]
port: u16,
}模拟重命名和默认值
属性的逻辑就是键映射加上备用值。下面这个可运行示例使用 HashMap 模拟了这种行为。
use std::collections::HashMap;
fn main() {
let mut input: HashMap<&str, &str> = HashMap::new();
input.insert("userName", "Alice");
let user_name = input.get("userName").copied().unwrap_or("anon");
let port = input.get("port").copied().unwrap_or("8080");
println!("user_name={} port={}", user_name, port);
}反序列化时使用别名
alias 在读取时接受备用键名,这在同时支持新旧字段名时很有帮助。
use serde::Deserialize;
#[derive(Deserialize)]
struct User {
#[serde(alias = "username")]
name: String,
}展平
flatten 会将嵌套结构体的字段内联到父对象中,从而去除 JSON 中的一层嵌套。
use serde::Serialize;
#[derive(Serialize)]
struct Meta { page: u32 }
#[derive(Serialize)]
struct Resp {
data: String,
#[serde(flatten)]
meta: Meta,
}通过模块自定义
如需完全控制,请将 with 指向一个提供 serialize 和 deserialize 函数的模块,例如用于格式化时间戳。
use serde::Serialize;
#[derive(Serialize)]
struct Event {
#[serde(with = "my_date_format")]
at: i64,
}枚举标记
使用 tag(内部标记)或 untagged 控制枚举的编码方式。这些设置会影响变体类型对应的 JSON 结构。
use serde::Serialize;
#[derive(Serialize)]
#[serde(tag = "type")]
enum Event {
Click { x: i32, y: i32 },
Key { code: u8 },
}快速检查
测试您对自定义序列化的理解。
回顾
您已经学习了如何自定义序列化:
rename和rename_all用于映射字段名skip和skip_serializing_if控制输出default和alias简化反序列化flatten、with和枚举的tag用于处理数据结构
下一步:了解 JSON 之外的格式。
常见问题解答
「自定义序列化」课时是免费的吗?
是的 — 「自定义序列化」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。
「自定义序列化」这节课中我会学到什么?
字段属性 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn Rust Coding 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「自定义序列化」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn Rust Coding 课中编写并运行代码吗?
能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。