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

如何反序列化包含嵌套JSON字符串的JSON对象?

解决嵌套JSON字符串的反序列化问题

这个问题我之前也碰到过!核心原因是你JSON里的b字段是字符串形式的JSON,但你的Test结构体里b定义的是B类型,serde默认会直接把它当成结构体来解析,自然就类型不匹配 panic 了。给你两种实用的解决办法:

方法一:自定义反序列化函数(推荐)

利用serde的deserialize_with属性,给b字段指定一个自定义的反序列化逻辑——先把字符串解析出来,再把这个字符串转成B结构体。

首先写一个通用的辅助函数,它能把JSON字符串反序列化成任意实现了Deserialize的类型:

use serde::{Deserialize, Deserializer};

fn deserialize_json_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
    T: Deserialize<'de>,
    D: Deserializer<'de>,
{
    // 先把输入反序列成字符串
    let json_str = String::deserialize(deserializer)?;
    // 再把字符串解析成目标类型,转换错误格式适配serde的错误类型
    serde_json::from_str(&json_str).map_err(serde::de::Error::custom)
}

然后修改你的Test结构体,给b字段加上属性:

#[derive(Deserialize)]
struct B {
    c: String,
    d: u32,
}

#[derive(Deserialize)]
struct Test {
    a: String,
    // 指定用我们写的函数来反序列化b字段
    #[serde(deserialize_with = "deserialize_json_string")]
    b: B,
}

// 现在再运行你的反序列化代码就不会panic了
fn main() {
    let object: Test = serde_json::from_str(
        r#"
        {
            "a": "string",
            "b": "{\"c\":\"c_string\",\"d\":1234}"
        }
        "#,
    ).unwrap();
    
    println!("a: {}, c: {}, d: {}", object.a, object.b.c, object.b.d);
}

方法二:中间结构体中转

如果不想写自定义函数,也可以先把JSON反序列化到一个中间结构体,手动把b字段的字符串解析成B,再转换成最终的Test结构体:

use serde::Deserialize;

#[derive(Deserialize)]
struct B {
    c: String,
    d: u32,
}

#[derive(Deserialize)]
// 中间结构体,b字段是String类型
struct IntermediateTest {
    a: String,
    b: String,
}

#[derive(Deserialize)]
struct Test {
    a: String,
    b: B,
}

fn main() {
    let intermediate: IntermediateTest = serde_json::from_str(
        r#"
        {
            "a": "string",
            "b": "{\"c\":\"c_string\",\"d\":1234}"
        }
        "#,
    ).unwrap();
    
    // 手动把字符串解析成B
    let b = serde_json::from_str(&intermediate.b).unwrap();
    let object = Test {
        a: intermediate.a,
        b,
    };
    
    println!("a: {}, c: {}, d: {}", object.a, object.b.c, object.b.d);
}

注意:示例里用了unwrap()是为了简化代码,实际生产环境中建议用Result来处理错误,避免程序panic。

内容的提问来源于stack exchange,提问作者Nils André

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:14:06