Rust笔记:serde使用教程

186 阅读3分钟

前言

serde 是 Rust 中一个非常流行的库,用于序列化和反序列化数据。它支持多种数据格式,例如 JSON、YAML、TOML 等。serde 提供了强大的功能,可以将 Rust 结构体和枚举与这些格式相互转换。

安装 serde

首先,在你的 Cargo.toml 文件中添加 serde 及其支持的格式库,例如 serde_json

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

使用 serde 进行序列化和反序列化

以下是如何使用 serdeserde_json 将 Rust 结构体与 JSON 格式互相转换的示例。

定义数据结构

首先,定义一个数据结构,并使用 #[derive(Serialize, Deserialize)] 来自动生成序列化和反序列化的实现:

use serde::{Serialize, Deserialize};

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

序列化

将 Rust 结构体转换为 JSON 字符串称为序列化。使用 serde_json::to_string 完成此操作:

fn main() {
    let person = Person {
        name: String::from("Alice"),
        age: 30,
        email: String::from("alice@example.com"),
    };

    // 序列化为 JSON 字符串
    let json_string = serde_json::to_string(&person).unwrap();
    println!("Serialized JSON: {}", json_string);
}

反序列化

将 JSON 字符串转换为 Rust 结构体称为反序列化。使用 serde_json::from_str 完成此操作:

fn main() {
    let json_data = r#"
        {
            "name": "Bob",
            "age": 25,
            "email": "bob@example.com"
        }
    "#;

    // 反序列化为 Person 结构体
    let person: Person = serde_json::from_str(json_data).unwrap();
    println!("Deserialized struct: {:?}", person);
}

使用 serde 的高级功能

serde 还支持许多高级功能,例如自定义序列化/反序列化逻辑、跳过某些字段、重命名字段等。

跳过字段

可以使用 #[serde(skip_serializing, skip_deserializing)] 属性来跳过某些字段:

#[derive(Serialize, Deserialize, Debug)]
struct Config {
    username: String,
    #[serde(skip_serializing)]
    password: String,
}

在这个例子中,password 字段不会被序列化到 JSON 中。

重命名字段

可以使用 #[serde(rename = "new_name")] 属性来重命名字段:

#[derive(Serialize, Deserialize, Debug)]
struct User {
    #[serde(rename = "userName")]
    username: String,
    age: u8,
}

这样,username 字段在 JSON 中会被命名为 userName

批量重命名所有字段或变体

可以使用 #[serde(rename_all = "case")]

  • 批量重命名所有字段或变体,case 可以是 lowercaseUPPERCASEPascalCasecamelCasesnake_casekebab-case 等。
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct MyStruct {
    firstName: String,
    lastName: String,
}

默认值

可以使用 #[serde(default)]

-   反序列化时,如果字段缺失,则使用该字段的默认值。
#[derive(Serialize, Deserialize)]
struct MyStruct {
    id: u32,
    #[serde(default)]
    optional_field: String,
}

自定义序列化/反序列化

你可以通过实现 serde::Serializeserde::Deserialize trait 来自定义序列化和反序列化逻辑。

  1. #[serde(serialize_with = "path")]

    • 使用指定的函数进行自定义序列化。
    use serde::{Serialize, Serializer};
    
    fn serialize_as_hex<S>(x: &u32, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&format!("{:X}", x))
    }
    
    #[derive(Serialize, Deserialize)]
    struct MyStruct {
        #[serde(serialize_with = "serialize_as_hex")]
        id: u32,
    }
    
  2. #[serde(deserialize_with = "path")]

    • 使用指定的函数进行自定义反序列化。
    use serde::{Deserialize, Deserializer};
    
    fn deserialize_from_hex<'de, D>(deserializer: D) -> Result<u32, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        u32::from_str_radix(&s, 16).map_err(serde::de::Error::custom)
    }
    
    #[derive(Serialize, Deserialize)]
    struct MyStruct {
        #[serde(deserialize_with = "deserialize_from_hex")]
        id: u32,
    }
    

总结

serde 是一个功能强大且灵活的库,适用于各种序列化和反序列化需求。通过使用 serde,你可以轻松地在 Rust 结构体和多种数据格式之间进行转换。serde 的自动派生功能和丰富的属性选项使其在处理复杂数据结构时非常高效。