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

Rust中API JSON反序列化:处理字段为Vec或Null的异常问题

解决JSON反序列化时null与Vec类型不兼容的问题

问题背景

API返回的JSON数据如下:

[
    {
        "id":"b8b2f91952f1fb757663073fa8f6be73",
        "name":"test1",
        "colors":[
            {
                "name":"Red",
                "number":"0"
            },
            {
                "name":"Blue",
                "number":"1"
            }
        ]
    },
    {
        "id":"91ff6b1fb7b8b2f57663073952fa8e73",
        "name":"test2",
        "colors": null
    }
]

对应的Rust结构体定义:

#[derive(Serialize, Deserialize, Debug)]
struct FinalScores {
    id: String,
    name: String,
    colors: Vec<Colors>
}

#[derive(Serialize, Deserialize, Debug)]
struct Colors{
    name: String,
    number: String
}

反序列化代码:

let score_request_url = "https://api.test.com";

let score_response = reqwest::get(score_request_url).await?;

let score_infos: Vec<FinalScores> = score_response.json().await?;

运行时出现错误:

invalid type: null, expected a string

错误原因

结构体中colors字段被定义为Vec<Colors>,属于非可选的数组类型,但API返回的该字段存在null值,serde默认不支持将null直接映射到非可选的非空类型,导致反序列化失败。

解决方案

方案1:将字段改为可选类型

把colors的类型改为Option<Vec<Colors>>,这样API返回null时会被反序列化为None,返回数组时则为Some(Vec<Colors>),完整结构体定义:

#[derive(Serialize, Deserialize, Debug)]
struct FinalScores {
    id: String,
    name: String,
    colors: Option<Vec<Colors>>
}

#[derive(Serialize, Deserialize, Debug)]
struct Colors{
    name: String,
    number: String
}

这种方案会保留原始数据中是否为null的信息,后续业务逻辑可以通过判断Some/None来分别处理。

方案2:将null自动转为空数组

如果业务上不需要区分null和空数组,可以使用serde的属性将null映射为空Vec,同时可选地在序列化时跳过空数组(避免输出冗余内容),结构体定义:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct FinalScores {
    id: String,
    name: String,
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    colors: Vec<Colors>
}

#[derive(Serialize, Deserialize, Debug)]
struct Colors{
    name: String,
    number: String
}
  • #[serde(default)]:反序列化时,若字段为null或缺失,会使用Vec的默认值(空数组)
  • #[serde(skip_serializing_if = "Vec::is_empty")]:序列化时,如果数组为空则不输出该字段,可根据需求去掉此属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:20:30