代码之家  ›  专栏  ›  技术社区  ›  zwl1619

在rust中迭代数组时出错

  •  0
  • zwl1619  · 技术社区  · 3 年前

    我正在读取一个json文件,然后迭代一个数组,出现了一个错误:

    D:\workspace\rust-projects\hello-rust (master)
    λ cargo run
       Compiling hello-rust v0.1.0 (D:\workspace\rust-projects\hello-rust)
    error[E0599]: no method named `iter` found for enum `Value` in the current scope
      --> src\main.rs:69:46
       |
    69 |             for item in note["sectionNotes"].iter() {
       |                                              ^^^^ method not found in `Value`
    
    For more information about this error, try `rustc --explain E0599`.
    error: could not compile `hello-rust` due to previous error
    

    代码如下:

    test.json

    {
        "sound": {
            "soundNotes": [
                {
                    "sectionNotes": [],
                    "lengthInSteps": 16
                },
                {
                    "sectionNotes": [
                        [
                            11256.236,
                            2,
                            0
                        ]
                    ],
                    "lengthInSteps": 17
                },
                {
                    "sectionNotes": [
                        [
                            13122.965,
                            3,
                            1
                        ],
                        [
                            13500,
                            0,
                            2
                        ]
                    ],
                    "lengthInSteps": 18
                }
            ]
        }
    }
    

    货物.toml

    [dependencies]
    delay_timer = "0.10.1"
    serde_json = "1.0"
    anyhow = "1.0.51"
    smol = "1.2.5"
    

    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() {
    
    }
    
    
    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();
    
        let song_notes=get_section_notes();
        
        let body = create_async_fn_body!({
        
            for note in song_notes.iter() {
                for item in note["sectionNotes"].iter() {
                Timer::after(Duration::from_millis(item[0].round())).await;
                     println!("{}", item);;
                 }
            }
    
        });
    
        // Build the task and assign 1 to it
        task_builder
            .set_task_id(1)
            .spawn(body)
    }
    
    

    请帮忙,谢谢!

    更新1:
    修改为之后 for item in note["sectionNotes"].as_array().unwrap() ,是这样的:

    D:\workspace\rust-projects\hello-rust (master)
    λ cargo run
       Compiling hello-rust v0.1.0 (D:\workspace\rust-projects\hello-rust)
    error[E0599]: no method named `round` found for enum `Value` in the current scope
      --> src\main.rs:70:60
       |
    70 |                 Timer::after(Duration::from_millis(item[0].round())).await;
       |                                                            ^^^^^ method not found in `Value`
    
    For more information about this error, try `rustc --explain E0599`.
    error: could not compile `hello-rust` due to previous error
    

    更新2:

    for note in song_notes.iter() {
                for item in note["sectionNotes"].as_array().unwrap() {
                    let mut time=item[0].as_u64().unwrap();
                    Timer::after(Duration::from_millis(time)).await;
                    println!("{}", time);
                 }
            }
    

    错误

    λ cargo run
       Compiling hello-rust v0.1.0 (D:\workspace\rust-projects\hello-rust)
    error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
      --> src\main.rs:66:16
       |
    66 |       let body = create_async_fn_body!({
       |  ________________^
    67 | |
    68 | |         for note in song_notes.iter() {
       | |                     ---------- closure is `FnOnce` because it moves the variable `song_notes` out of its environment
    69 | |             for item in note["sectionNotes"].as_array().unwrap() {
    ...  |
    75 | |
    76 | |     });
       | |______^ this closure implements `FnOnce`, not `Fn`
    ...
    81 |           .spawn(body)
       |            ----- the requirement to implement `Fn` derives from here
       |
       = note: this error originates in the macro `create_async_fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    For more information about this error, try `rustc --explain E0525`.
    error: could not compile `hello-rust` due to previous error
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   AlexNe    3 年前

    修复了上述错误。

    use anyhow::Result;
    use delay_timer::prelude::*;
    use serde_json::{Result as SResult, Value};
    use smol::Timer;
    use std::fs::File;
    use std::io::BufReader;
    use std::time::Duration;
    
    fn main() {}
    
    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();
    
        
        let body = create_async_fn_body!({
            let song_notes = get_section_notes();  //put it here
            for note in song_notes.iter() {
                for item in note["sectionNotes"].as_array().iter() {
                    // Error fixed
                    Timer::after(Duration::from_millis(item[0].as_f64().unwrap().round() as u64)).await;
                    println!("{:?}", item);
                }
            }
        });
    
        // Build the task and assign 1 to it
        task_builder.set_task_id(1).spawn(body)
    }