我正在编写一个Rust程序,它可以执行以下操作:
1.创建一个线程数组来生成,每个线程都包含一个变量,该变量存储目录的路径:
let (tx, rx) = mpsc::channel();
let handles: Vec<_> = dir_list
.into_iter()
.map(|dir_path| {
let path2 = dir_path.clone();
let txc = tx.clone();
thread::spawn(move || func(txc, &Path::new(&path2)))
})
.collect();
for h in handles {
let _ = h.join();
}
字符串
1.在func()
中,运行一个for循环(在每个线程上),该循环使用walkdir
crate(https://crates.io/crates/walkdir)遍历所述路径,并通过tx
向接收者发送相应的消息:
for entry in WalkDir::new(&path) {
if entry.is_err() {
tx.send(Err((entry.unwrap_err(), 0)).unwrap());
continue;
}
let entry = entry.unwrap(); // !
match func2(&entry) {
Ok(len) => {
tx.send((entry.file_name(), Ok(len))).unwrap(); // !
}
Err(e) => {
if e != SubDirError { // a custom error
tx.send((entry.file_name(), Err(e.into()))).unwrap(); // !
}
}
}
}
drop(tx);
型
编译器抱怨entry.file_name()
的生存期问题。似乎这个错误意味着它应该存在于整个函数中,这是不可能的,因为不同的目录路径使用了for循环:
error[E0597]: `entry` does not live long enough
--> src/dir.rs:40:26
|
24 | [<function header, redacted for clarity>]
| - let's call the lifetime of this reference `'1`
...
35 | let entry = entry.unwrap();
| ----- binding `entry` declared here
...
40 | tx.send((entry.file_name(), Ok(len))).unwrap();
| ---------^^^^^^^^^^^^^^^^^-----------
| | |
| | borrowed value does not live long enough
| argument requires that `entry` is borrowed for `'1`
...
53 | }
| - `entry` dropped here while still borrowed
型
我该怎么办?如果由于消息和线程的所有权问题而无法解决这个问题,我应该尝试其他什么替代方案?我需要在每次迭代时将entry.file_name()
传递给通道。
1条答案
按热度按时间xiozqbni1#
通过将
.to_os_string()
附加到entry.file_name()
来解决;即,将其从&OsStr
升级到OsString
。事实证明,您应该在通道中发送拥有的类型而不是借用的引用,因为Sender
的生存期取决于类型(?).