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

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的异步任务闭包默认要求实现Fn trait支持多次执行,直接转移外部变量所有权会导致闭包只能执行一次。可以将变量提前克隆后移入闭包,也可以直接把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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:18:05