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

在Rust中如何将JSON反序列化为多个结构体?

高效将指定JSON反序列化为两个Rust结构体的方法

先修正问题中的语法问题

原JSON的键未加双引号(不符合JSON规范),原Rust结构体字段用分号分隔(不符合Rust语法),修正后内容如下:

给定JSON数据:

{
   "name": "John",
   "age": "30"
}

修正后的Rust结构体:

struct Name {
    name: String,
}

struct Age {
    age: i32,
}

解决方案(基于Rust标准JSON处理库serde+serde_json)

方法一:临时结构体一次性解析(推荐,性能最优)

只解析一次JSON,再将字段拆分到两个目标结构体,避免重复解析开销。

  1. 给临时结构体和目标结构体派生Deserialize宏,用于反序列化
  2. 先把JSON解析到临时结构体,再提取字段构造目标实例

代码示例:

use serde::Deserialize;

// 临时结构体,匹配JSON的完整结构
#[derive(Deserialize)]
struct TempUser {
    name: String,
    // 处理JSON中字符串类型的数字转i32,这里用serde_aux简化转换
    #[serde(deserialize_with = "serde_aux::prelude::deserialize_number_from_string")]
    age: i32,
}

#[derive(Deserialize, Debug)]
struct Name {
    name: String,
}

#[derive(Deserialize, Debug)]
struct Age {
    age: i32,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_str = r#"{
       "name": "John",
       "age": "30"
    }"#;

    // 一次性解析JSON到临时结构体
    let temp_user: TempUser = serde_json::from_str(json_str)?;

    // 构造目标结构体
    let name_struct = Name { name: temp_user.name };
    let age_struct = Age { age: temp_user.age };

    println!("{:?}", name_struct);
    println!("{:?}", age_struct);

    Ok(())
}

如果不想依赖serde_aux,可以手动处理类型转换:把临时结构体的age设为String,再用parse::<i32>()转成数字。

方法二:通过serde_json::Value分步提取

无需定义临时结构体,先把JSON解析为通用Value类型,再手动提取字段并转换类型。性能略逊于方法一(需要二次解析字段),但灵活性更高。

代码示例:

use serde_json::Value;

#[derive(Debug)]
struct Name {
    name: String,
}

#[derive(Debug)]
struct Age {
    age: i32,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_str = r#"{
       "name": "John",
       "age": "30"
    }"#;

    // 解析为通用Value类型
    let json_value: Value = serde_json::from_str(json_str)?;

    // 提取name字段构造Name结构体
    let name_struct = Name {
        name: json_value["name"].as_str().ok_or("name字段不存在或非字符串类型")?.to_string(),
    };

    // 提取age字段并转成i32,构造Age结构体
    let age_struct = Age {
        age: json_value["age"].as_str().ok_or("age字段不存在或非字符串类型")?.parse()?,
    };

    println!("{:?}", name_struct);
    println!("{:?}", age_struct);

    Ok(())
}

依赖配置

需要在Cargo.toml中添加以下依赖:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# 使用方法一时需要添加:
serde_aux = "1.0"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:29