Rust读取JSON遍历serde_json::Value数组出现E0599等错误如何解决
Rust读取JSON遍历数组报错解决方案
各个报错的对应修复逻辑
- 报错E0599(无iter方法):
serde_json::Value是枚举类型,只有它实际为Array变体时才可遍历,需要先调用as_array()方法转换为数组引用,同时get_section_notes()返回的是Result类型,需要先 unwrap 拿到实际的Value值再操作。 - 报错E0599(无round方法):JSON中读取的数值仍然是
Value类型,需要先调用as_f64()转换为原生浮点类型后,才可以调用round()方法做数值计算。 - 报错E0525(闭包仅实现FnOnce):
delay_timer的异步任务闭包默认要求实现Fntrait支持多次执行,直接转移外部变量所有权会导致闭包只能执行一次。可以将变量提前克隆后移入闭包,也可以直接把JSON读取逻辑放到闭包内部避免外部变量捕获,本次采用更简单的提前克隆方案。
修正后完整代码
main.rs
use delay_timer::prelude::*; use anyhow::Result; use smol::Timer; use std::time::Duration; use std::fs::File; use std::io::BufReader; use serde_json::{Result as SResult, Value}; fn main() -> Result<()> { let delay_timer = DelayTimerBuilder::default().build(); // 注册任务 let task = build_task_async_print()?; delay_timer.add_task(task)?; // 阻塞等待任务执行完成,可根据需求调整等待时长 std::thread::sleep(Duration::from_secs(20)); Ok(()) } fn get_section_notes() -> SResult<Value> { let file = File::open("test.json").expect("file should open read only"); let reader = BufReader::new(file); let mut v: Value = serde_json::from_reader(reader)?; Ok(v["sound"]["soundNotes"].take()) } fn build_task_async_print() -> Result<Task, TaskError> { let mut task_builder = TaskBuilder::default(); // 提前拿到JSON数据,处理Result let song_notes = get_section_notes().unwrap(); // 提前克隆数据供闭包捕获,满足Fn trait要求 let song_notes_clone = song_notes.clone(); let body = create_async_fn_body!(move { // 先转数组再遍历 for note in song_notes_clone.as_array().unwrap() { // 转数组后遍历sectionNotes for item in note["sectionNotes"].as_array().unwrap() { // 先转f64取整后转u64传入Duration let time = item[0].as_f64().unwrap().round() as u64; Timer::after(Duration::from_millis(time)).await; println!("{}", item); } } }); // 设置任务只执行一次,符合单次遍历需求 task_builder .set_task_id(1) .set_frequency_once_by_second(0) .spawn(body) }
额外说明
如果不需要任务重复执行,也可以通过set_frequency_once_by_second(0)设置任务启动后立即执行一次,不需要支持闭包多次调用,也能解决FnOnce的报错问题。
生产环境建议把所有unwrap()替换为规范的错误处理逻辑,避免非法JSON格式导致程序崩溃。
内容的提问来源于stack exchange,提问作者zwl1619
相关产品推荐
相关产品推荐

