如何用Serde在Rust中解析JSON文件?解析报错求修正
修复Rust JSON解析问题的方案
下面是针对你遇到的JSON解析错误的具体修复步骤和原因分析:
1. 修正JSON格式错误
JSON不支持//风格的单行注释,你提供的JSON中的//(报错所在行)会导致解析器报错,必须删除该行。修正后的JSON如下:
{ "comment": ["some comments"], "data": [ ["name", "line 1"], ["name", ["line 1", "line 2"]], ["name", "line 1"] ] }
2. 修正结构体类型与JSON结构不匹配的问题
你的原结构体定义和JSON的结构存在多处不匹配,下面是修正后的结构体代码:
use serde::Deserialize; use std::fs; // 遵循Rust命名规范,结构体名使用大驼峰 #[derive(Debug, Deserialize)] struct MyData { // JSON中comment是字符串数组,对应Rust的Vec<String> comment: Vec<String>, data: Vec<SubData>, } // 处理pattern字段的两种可能类型:单个字符串或字符串数组 #[derive(Debug, Deserialize)] #[serde(untagged)] enum Pattern { Single(String), Multiple(Vec<String>), } // 用元组结构体匹配JSON中的双元素数组结构 #[derive(Debug, Deserialize)] struct SubData( String, // 自定义反序列化,把单个字符串或数组统一转为Vec<String> #[serde(deserialize_with = "pattern_to_vec")] Vec<String>, ); // 自定义反序列化函数,将Pattern枚举转为Vec<String> fn pattern_to_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error> where D: serde::Deserializer<'de>, { let pattern = Pattern::deserialize(deserializer)?; match pattern { Pattern::Single(s) => Ok(vec![s]), Pattern::Multiple(v) => Ok(v), } }
3. 修正后的读取代码
读取代码无需大幅修改,保持原有逻辑即可:
pub fn read_json() { let path = "./src/my_file.json"; let data = fs::read_to_string(path).expect("Unable to read file"); let obj: MyData = serde_json::from_str(&data).expect("Unable to parse"); println!("{:?}", obj); }
错误原因详解
- 注释导致的JSON格式错误:JSON官方规范不允许
//注释,解析器会将其视为无效语法,进而导致解析偏移,可能触发类似missing field的错误。 comment类型不匹配:JSON中的comment是["some comments"](字符串数组),但你原结构体定义为String,类型不兼容,必须改为Vec<String>。data结构不匹配:JSON的data数组元素是双元素数组(如["name", "line 1"]),但原结构体sub_data是键值对结构(serde默认会解析为JSON对象{"name": "...", "pattern": "..."}),两者结构完全不同。通过将SubData定义为元组结构体,让serde直接解析双元素数组;同时用枚举和自定义反序列化处理pattern字段的两种可能类型。
内容的提问来源于stack exchange,提问作者Prad
相关产品推荐
相关产品推荐

