gpt4 book ai didi

json - 如何使用 Serde 反序列化包含空值的 JSON 文件?

转载 作者:行者123 更新时间:2023-11-29 07:47:11 33 4
gpt4 key购买 nike

我想反序列化来自 Bowserinator on github 的化学元素 JSON 文件使用Serde。为此,我创建了一个包含所有必需字段的结构并派生了所需的宏:

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
name: String,
appearance: String,
atomic_mass: f64,
boil: f64,
category: String,
#[serde(default)]
color: String,
density: f64,
discovered_by: String,
melt: f64,
#[serde(default)]
molar_heat: f64,
named_by: String,
number: String,
period: u32,
phase: String,
source: String,
spectral_img: String,
summary: String,
symbol: String,
xpos: u32,
ypos: u32,
}

在到达包含“空”值的字段之前,它工作正常。例如。对于字段 "color": null, 在 Helium 中。

我收到的错误消息是 { code: Message("invalid type: unit value, expected a string"), line: 8, column: 17 for this field.

我尝试了 #[serde(default)] 宏。但这仅在 JSON 文件中缺少该字段时有效,而不是在存在 null 值时。

我喜欢使用标准宏进行反序列化,避免编写访问者特征。有没有我想念的把戏?

最佳答案

出现反序列化错误是因为struct定义与传入的对象不兼容:color字段也可以是null,也可以是字符串,但是给这个字段String 类型强制您的程序总是期待一个字符串。这是默认行为,这是有道理的。请注意,String(或其他容器,例如 Box)在 Rust 中不是“可空的”。至于不触发默认值的 null 值,这正是 Serde 的工作方式:如果对象字段不存在,它会工作,因为您已经添加了默认字段属性。另一方面,值为 null 的字段“color”并不等同于根本没有字段。

解决这个问题的一种方法是调整我们应用程序的规范以接受null | string,由@user25064 的回答指定:

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
color: Option<String>,
}

Playground with minimal example

另一种方法是为该字段编写我们自己的反序列化例程,它将接受 null 并将其转换为 String 类型的其他内容。这可以通过属性 #[serde(deserialize_with=...)] 来完成。

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
#[serde(deserialize_with="parse_color")]
color: String,
}

fn parse_color<'de, D>(d: D) -> Result<String, D::Error> where D: Deserializer<'de> {
Deserialize::deserialize(d)
.map(|x: Option<_>| {
x.unwrap_or("black".to_string())
})
}

Playground

另见:

关于json - 如何使用 Serde 反序列化包含空值的 JSON 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44205435/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com