You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Rust的Serde构建对应指定JSON格式的结构体?

问题解答

1. 是否需要为每个嵌套层级创建结构体?

不一定,有两种常用方案:

  • 显式结构体(推荐):像你现在这样为每个嵌套层级定义结构体,优点是类型安全、支持IDE自动补全、编译期就能检查错误,适合结构固定且需要复用的场景。
  • 匿名结构简化:对于临时或简单的嵌套,可以用serde_json::Value、嵌套的HashMap/Vec,或者Serde的匿名结构体语法,但可读性和类型安全性会下降,适合快速构建一次性结构。

举个简化示例(无需全量结构体):

use serde::Serialize;
use serde_json::json;

#[derive(Serialize)]
struct DBRow {
    parent: std::collections::HashMap<String, String>,
    properties: std::collections::HashMap<String, serde_json::Value>,
}

// 直接填充数据
let row = DBRow {
    parent: [("database_id".to_string(), "123".to_string())].into(),
    properties: [
        (
            "title".to_string(),
            json!({
                "title": [
                    { "text": { "content": "Yurts in Big Sur, 123" } }
                ]
            })
        )
    ].into(),
};

但这种方式丢失了类型检查,比如写错字段名不会触发编译报错,复杂场景更推荐显式结构体。

2. 如何处理两个同名的"title"属性?

你当前的处理方式是正确的:用不同的结构体来区分不同层级的title上下文:

  • 外层Properties结构体的title字段,对应JSON中properties下的"title"键;
  • 内层PropTitle结构体的title字段,对应JSON中该对象下的"title"数组;
    Serde会根据结构体字段名自动生成对应的JSON键名,完美匹配目标结构。

不过你的代码有一处错误:Text结构体的定义不符合JSON结构。JSON中是{ "text": { "content": "..." } },需要调整相关结构体:

#[derive(Serialize)]
struct TextWrapper {
    text: TextContent,
}

#[derive(Serialize)]
struct TextContent {
    content: String,
}

// 同步修改PropTitle
#[derive(Serialize)]
struct PropTitle {
    title: Vec<TextWrapper>,
}

修正后的完整代码

use serde::Serialize;

#[derive(Serialize)]
struct DBRow {
    parent: Parent,
    properties: Properties,
}

#[derive(Serialize)]
struct Parent {
    database_id: String,
}

#[derive(Serialize)]
struct Properties {
    title: PropTitle,
}

#[derive(Serialize)]
struct PropTitle {
    title: Vec<TextWrapper>,
}

#[derive(Serialize)]
struct TextWrapper {
    text: TextContent,
}

#[derive(Serialize)]
struct TextContent {
    content: String,
}

// 使用示例
fn main() -> Result<(), serde_json::Error> {
    let row = DBRow {
        parent: Parent {
            database_id: "123".to_string(),
        },
        properties: Properties {
            title: PropTitle {
                title: vec![TextWrapper {
                    text: TextContent {
                        content: "Yurts in Big Sur, 123".to_string(),
                    },
                }],
            },
        },
    };

    let json_str = serde_json::to_string_pretty(&row)?;
    println!("{}", json_str);
    Ok(())
}

这段代码会生成你需要的目标JSON结构。

内容的提问来源于stack exchange,提问作者Xin Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:10:18