返回文章列表

文章

关于#[serde(rename_all = "camelCase")]的作用范围

目录
  1. rename_all 的作用范围
  2. 示例说明
  3. 输出结果
  4. 如果想要重命名 Value 内部的字段

rename_all 的作用范围#

#[serde(rename_all = "camelCase")] 只作用于当前结构体的直接字段名,不会影响:

  1. 字段值的内部结构
  2. serde_json::Value** 或其他动态类型的内部字段**

示例说明#

use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NewsItem {
    pub id: String,
    pub item_name: String,  // 这个会被重命名为 "itemName"
    pub items: Vec<Value>,  // Value 内部的字段不受影响
}

fn main() {
    let json_data = r#"
    {
        "id": "123",
        "itemName": "test item",  // 注意:item_name 被重命名了
        "items": [
            {
                "some_field": "value",      // 这个保持原样
                "another_field": 42         // 这个也保持原样
            }
        ]
    }"#;

    let news_item: NewsItem = serde_json::from_str(json_data).unwrap();
    println!("{:?}", news_item);
}

输出结果#

在序列化/反序列化时:

  • item_name"itemName" (被重命名)
  • items 数组中的 some_fieldanother_field 保持原样

如果想要重命名 Value 内部的字段#

如果你需要控制 Value 内部的字段命名,你需要:

  1. 定义具体的结构体 而不是使用 Value
  2. **在每个嵌套结构体上都添加 **rename_all
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ItemDetail {
    pub some_field: String,      // 会被重命名为 "someField"
    pub another_field: i32,      // 会被重命名为 "anotherField"
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NewsItem {
    pub id: String,
    pub item_name: String,
    pub items: Vec<ItemDetail>,  // 现在内部的字段也会被重命名
}

总结:rename_all 只影响直接应用该属性的结构体的字段名,不会穿透到动态类型如 Value 的内部。