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

如何在Serde反序列化空数组时触发错误?

可行方案

针对你需要在反序列化空数组时触发错误的需求,以下是几种可行的实现方案:

方案1:自定义反序列化逻辑(无需额外依赖)

这种方式不需要引入第三方库,通过手动实现Serde的Deserialize trait添加空数组校验逻辑,有两种具体实现方式:

方式A:包装非空数组类型(复用性高)

如果项目中有多个地方需要验证非空数组,推荐定义一个通用的包装类型,避免重复代码:

use serde::{Deserialize, Deserializer};

// 定义包装非空数组的结构体
#[derive(Debug, Deserialize)]
struct NonEmptyVec<T>(Vec<T>);

// 为包装类型实现自定义反序列化
impl<T> Deserialize for NonEmptyVec<T>
where
    T: Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // 先完成基础的数组反序列化
        let vec = Vec::deserialize(deserializer)?;
        // 校验数组是否为空,为空则返回自定义错误
        if vec.is_empty() {
            return Err(serde::de::Error::custom("数组不能为空"));
        }
        Ok(NonEmptyVec(vec))
    }
}

// 修改原结构体,使用包装类型替代普通Vec
#[derive(Debug, Deserialize)]
struct Doc {
    nums: NonEmptyVec<i32>,
}

fn main() {
    // 测试空数组场景:会触发反序列化错误
    let empty_data = r#"{"nums": []}"#;
    match serde_json::from_str::<Doc>(empty_data) {
        Ok(doc) => dbg!(doc),
        Err(e) => eprintln!("反序列化失败: {}", e),
    }

    // 测试非空数组场景:正常解析
    let valid_data = r#"{"nums": [1, 2, 3]}"#;
    let valid_doc = serde_json::from_str::<Doc>(valid_data).unwrap();
    dbg!(valid_doc);
}

方式B:直接为目标结构体实现反序列化

如果只是针对Doc结构体的nums字段做校验,可以直接为Doc实现Deserialize,省去包装类型:

use serde::{Deserialize, Deserializer};

#[derive(Debug)]
struct Doc {
    nums: Vec<i32>,
}

// 为Doc实现自定义反序列化逻辑
impl<'de> Deserialize<'de> for Doc {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // 定义临时结构体用于完成基础反序列化
        #[derive(Deserialize)]
        struct TempDoc {
            nums: Vec<i32>,
        }

        let temp = TempDoc::deserialize(deserializer)?;
        // 校验nums数组是否为空
        if temp.nums.is_empty() {
            return Err(serde::de::Error::custom("nums数组不能为空"));
        }
        Ok(Doc { nums: temp.nums })
    }
}

fn main() {
    let empty_data = r#"{"nums": []}"#;
    match serde_json::from_str::<Doc>(empty_data) {
        Ok(doc) => dbg!(doc),
        Err(e) => eprintln!("反序列化失败: {}", e),
    }
}

方案2:使用serde_with库简化校验

如果项目中已经引入serde_with库,可以用它提供的现成工具快速实现非空数组校验,减少手写代码量:

首先在Cargo.toml中添加依赖:

serde_with = "3.4"

然后编写代码:

use serde::Deserialize;
use serde_with::{serde_as, non_empty_vec};

#[serde_as]
#[derive(Debug, Deserialize)]
struct Doc {
    // 用serde_with的non_empty_vec反序列化函数校验数组非空
    #[serde(deserialize_with = "non_empty_vec")]
    nums: Vec<i32>,
}

fn main() {
    let empty_data = r#"{"nums": []}"#;
    match serde_json::from_str::<Doc>(empty_data) {
        Ok(doc) => dbg!(doc),
        Err(e) => eprintln!("反序列化失败: {}", e),
    }
}

当nums为空数组时,反序列化会返回包含"Expected non-empty Vec"的错误信息,无需手动编写校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:55:25