rust serde 常见用法

举报
福州司马懿 发表于 2025/12/03 16:06:34 2025/12/03
【摘要】 在 Rust 中,serde 是一个用于高效、通用序列化和反序列化的框架,而 serde_json 是其针对 JSON 格式的插件,提供了完整的 JSON 数据处理能力。以下是 serde 和 serde_json 的核心用法及详细说明: 一、基础依赖配置在 Cargo.toml 中添加依赖,启用 derive 特性以支持自动生成序列化/反序列化代码:[dependencies]serde ...

在 Rust 中,serde 是一个用于高效、通用序列化和反序列化的框架,而 serde_json 是其针对 JSON 格式的插件,提供了完整的 JSON 数据处理能力。以下是 serdeserde_json 的核心用法及详细说明:

一、基础依赖配置

Cargo.toml 中添加依赖,启用 derive 特性以支持自动生成序列化/反序列化代码:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

二、核心功能与用法

1. 结构体序列化与反序列化

通过 #[derive(Serialize, Deserialize)] 派生宏,使结构体支持 JSON 转换:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Person {
    name: String,
    age: u8,
}

fn main() -> serde_json::Result<()> {
    // 序列化:Rust 结构体 → JSON 字符串
    let person = Person { name: "Alice".to_string(), age: 30 };
    let json_str = serde_json::to_string(&person)?;
    println!("Serialized JSON: {}", json_str);

    // 反序列化:JSON 字符串 → Rust 结构体
    let deserialized_person: Person = serde_json::from_str(&json_str)?;
    println!("Deserialized struct: {:?}", deserialized_person);

    Ok(())
}

2. 自定义序列化行为

通过 Serde 属性(Attributes)调整字段名称、跳过空值等:

#[derive(Serialize, Deserialize, Debug)]
struct User {
    #[serde(rename = "full_name")] // 修改 JSON 字段名
    name: String,

    #[serde(skip_serializing_if = "Option::is_none")] // 跳过 None 值
    email: Option<String>,

    #[serde(rename_all = "snake_case")] // 枚举字段名转为蛇形命名
    role: Role,
}

#[derive(Serialize, Deserialize, Debug)]
enum Role {
    Admin,
    User,
}

3. 枚举序列化

支持枚举的序列化,可通过 taguntagged 属性控制 JSON 结构:

#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type")] // 生成 { "type": "Admin", ... }
enum UserType {
    Admin { permissions: Vec<String> },
    User { id: u32 },
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)] // 生成扁平结构,如 { "permissions": [...] } 或 { "id": 123 }
enum UntaggedUser {
    Admin(Vec<String>),
    User(u32),
}

4. 复杂嵌套结构

处理嵌套结构或动态字段(如 HashMap):

#[derive(Serialize, Deserialize, Debug)]
struct Config {
    settings: HashMap<String, Value>, // Value 是 serde_json::Value,可表示任意 JSON 值
}

// 使用示例
let config = Config {
    settings: [
        ("timeout".to_string(), serde_json::Value::Number(30.into())),
        ("debug".to_string(), serde_json::Value::Bool(true)),
    ].iter().cloned().collect(),
};
let json = serde_json::to_string(&config)?;
println!("{}", json);

5. 文件读写

直接读写 JSON 文件:

use std::fs::File;

fn main() -> serde_json::Result<()> {
    // 写入文件
    let person = Person { name: "Bob".to_string(), age: 25 };
    let mut file = File::create("person.json")?;
    serde_json::to_writer_pretty(&mut file, &person)?; // 格式化输出

    // 读取文件
    let json_data = std::fs::read_to_string("person.json")?;
    let deserialized: Person = serde_json::from_str(&json_data)?;
    println!("{:?}", deserialized);

    Ok(())
}

6. 错误处理

使用 Result 类型处理可能的错误:

fn parse_json(json_str: &str) -> Result<Person, serde_json::Error> {
    serde_json::from_str(json_str)
}

fn main() {
    match parse_json(r#"{"name": "Charlie", "age": "thirty"}"#) { // 故意传入错误类型
        Ok(person) => println!("{:?}", person),
        Err(e) => println!("Error: {}", e), // 输出错误信息
    }
}

7. 动态 JSON 处理

使用 serde_json::Value 处理未知结构的 JSON:

fn main() -> serde_json::Result<()> {
    let json_str = r#"{
        "name": "Dynamic",
        "tags": ["rust", "json"],
        "active": true
    }"#;

    let value: serde_json::Value = serde_json::from_str(json_str)?;
    println!("Name: {}", value["name"].as_str().unwrap());
    println!("Tags: {:?}", value["tags"].as_array().unwrap());

    Ok(())
}

三、高级特性

  • 远程类型派生:通过 #[serde(remote = "...")] 为外部类型生成序列化代码。
  • 透明包装:使用 #[serde(transparent)] 处理仅包含单个字段的结构体,避免额外嵌套。
  • 自定义序列化器:手动实现 SerializeDeserialize trait 以处理复杂逻辑。

四、性能与优势

  • 零运行时反射:基于 Rust 的 trait 系统,无反射开销,性能接近手写代码。
  • 泛型支持:可扩展至其他格式(如 YAML、TOML),只需替换数据格式库(如 serde_yaml)。
  • 生态丰富:与 reqwest(HTTP 客户端)、axum(Web 框架)等库无缝集成。

五、适用场景

  • API 开发:处理 HTTP 请求/响应的 JSON 数据。
  • 配置管理:读取和写入 JSON 配置文件。
  • 数据交换:与前端或其他服务通过 JSON 通信。
  • 日志与监控:结构化日志的序列化。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。