如何用Rust的serde_json反序列化含混合元素的JSON数组?
解决serde_json反序列化混合类型数组的问题
针对JSON中stuff字段包含混合类型(字符串或字符串数组)的反序列化需求,使用#[serde(untagged)]标记枚举是可行方案,关键要确保枚举变体准确对应JSON元素的实际类型。以下是完整的可运行实现:
首先在Cargo.toml中添加依赖:
[dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"
定义对应的结构体与枚举:
use serde::Deserialize; #[derive(Debug, Deserialize)] #[serde(untagged)] enum ListOrNestedList { // 匹配JSON中的单个字符串元素 Single(String), // 匹配JSON中的字符串数组元素 Nested(Vec<String>), } #[derive(Debug, Deserialize)] struct Entry { name: String, stuff: Vec<ListOrNestedList>, }
测试验证代码:
fn main() { let json_str = r#" { "name": "example", "stuff": [ "item 1", "item 2", [ "nested item 1", "nested item 2", "nested item 3" ] ] } "#; let entry: Entry = serde_json::from_str(json_str).unwrap(); println!("{:#?}", entry); }
错误原因分析
你之前触发panic,大概率是枚举变体的类型定义不符合JSON结构:
- 可能错误地将
Nested变体的类型定义为Vec<ListOrNestedList>(导致递归匹配逻辑混乱),而非直接对应JSON里的字符串数组Vec<String>; - 极少数情况下如果变体顺序不合理,也可能导致匹配失败,但
String和Vec<String>类型差异明显,顺序影响极小。
#[serde(untagged)]的逻辑是按枚举变体顺序依次尝试反序列化,只要某一变体匹配成功就停止处理,因此只要变体类型与JSON元素一一对应,就能正确解析混合类型数组。
内容的提问来源于stack exchange,提问作者Nicholas M. Van Horn
相关产品推荐
相关产品推荐

