首页 文章

如何解决这个Rust生命周期问题?

提问于
浏览
2

我试图并行读取目录中的文件的内容 . 我遇到了终身问题 .

我的代码看起来像这样:

use std::io::fs;
use std::io;
use std::collections::HashMap;
use std::comm;
use std::io::File;

fn main() {
    let (tx, rx) = comm::channel(); // (Sender, Receiver)

    let paths = fs::readdir(&Path::new("resources/tests")).unwrap();

    for path in paths.iter() {
        let task_tx = tx.clone();

        spawn(proc() {
            match File::open(path).read_to_end() {
                Ok(data) => task_tx.send((path.filename_str().unwrap(), data)),
                Err(e) => fail!("Could not read one of the files! Error: {}", e)
            };
        });
    }

    let mut results = HashMap::new();

    for _ in range(0, paths.len()) {
        let (filename, data) = rx.recv();

        results.insert(filename, data);
    }

    println!("{}", results);
}

我得到的编译错误是:

错误:路径活不够长注意:引用必须对静态生命周期有效...注意:...但借用的值仅对块在7:19有效

我也尝试在循环中使用 into_iter() (或之前的 move_iter() )而没有太大的成功 .

我怀疑它与产生的任务在整个 main() 范围之外仍然存在有关,但我不知道如何解决这种情况 .

1 回答

  • 4

    错误消息可能有点令人困惑,但它告诉您的是您正在尝试在任务中使用引用 path . 因为spawn正在使用 proc ,所以您只能使用可以将所有权转移到该任务的数据( Send kind) .

    要解决这个问题,你可以这样做(你可以使用move_iter但是你不能在循环后访问路径):

    for path in paths.iter() {
        let task_tx = tx.clone();
    
        let p = path.clone();
        spawn(proc() {
            match File::open(&p).read_to_end() {
    

    第二个问题是您尝试通过通道发送 &str (文件名) . 与使用的任务类型相同必须是 Send

    match File::open(&p).read_to_end() {
            Ok(data) => task_tx.send((p.filename_str().unwrap().to_string(), data)),
            Err(e) => fail!("Could not read one of the files! Error: {}", e)
        };
    

相关问题