index

Rust 簡易音訊數據讀工具

· 1min

Conclusion

// 260530 簡易音訊數據讀取器
use std::fs;

fn load_audio_samples(path: &str) -> Result<Vec<f32>, Box<dyn std::error::Error>> {
    let file = fs::read_to_string(path)?;
    let mut r: Vec<f32> = vec![];

    for line in file.lines() {
        r.push(line.parse::<f32>()?);
    }
    Ok(r)
}

fn main() {
    let audio_samples = load_audio_samples("samples.txt");

    match audio_samples {
        Ok(v) => println!("vec: {:?}, size: {}", v, v.len()), 
        Err(e) => println!("error: {}", e)
    }
}

Practice

Q1Ⅰ在 Closure 裡進行 return……?

由於 Rust 中 .map() 是惰性的,單純呼叫跟本不會執行,再加上 closure 並不是回傳 Result 或 Option,所以編譯器會報錯。

    content.lines().map(|line| {
        let mut r = line.parse()?;  // this function should return `Result` or `Option` to accept `?`
        samples.push(r);
    });

應該改用簡單直觀的 for 迴圈

    for line in content.lines() {
        samples.push(line.parse::<f32>()?);
    }

Q2Ⅰ列印檢查 Vector 的內容

可以使用 Rust 的除錯工具 dbg!

fn main() {
    let sample = load_audio_samples("samples.txt");
    dbg!(&sample);
}

Q3Ⅰ友善的錯誤訊息

使用 matchif let 來解構 Result,並在出錯時使用 eprintln!(輸出至標準錯誤流 Stderr)印出訊息

fn main() {
    match load_audio_samples("samples.txt") {
        Ok(samples) => {
            println!("音訊樣本載入成功!共讀取到 {} 個資料。", samples.len());
            println!("資料內容:{:?}", samples);
        }
        Err(err) => {
            eprintln!("❌ 讀取樣本時發生錯誤:{}", err);
        }
    }
    // dbg!(&sample);
}