Reputation: 21
I'm writing a Rust program that spawns an array of threads, each given the path of a directory. Each thread iterates through the said path with the walkdir crate and sends the nested paths through a channel:
use std::ffi::OsStr;
use std::path::Path;
use std::thread;
use std::sync::mpsc;
use walkdir::WalkDir;
fn func(tx: mpsc::Sender<&OsStr>, path: &Path) {
for entry in WalkDir::new(&path) {
if let Ok(entry) = entry {
tx.send(entry.file_name()).unwrap();
}
}
}
fn main() {
let dir_list: Vec<String> = ...;
let (tx, rx) = mpsc::channel();
let handles: Vec<_> = dir_list
.into_iter()
.map(|dir_path| {
let txc = tx.clone();
thread::spawn(move || func(txc, Path::new(&dir_path)))
})
.collect();
for h in handles {
let _ = h.join();
}
...
}
The compiler complains about lifetime issues with entry.file_name()
. Seems that the error means it should live throughout the entire function, which is not possible due to the use of a for loop for different directory paths:
error[E0597]: `entry` does not live long enough
--> src/main.rs:11:21
|
8 | fn func(tx: mpsc::Sender<&OsStr>, path: &Path) {
| - let's call the lifetime of this reference `'1`
9 | for entry in WalkDir::new(&path) {
10 | if let Ok(entry) = entry {
| ----- binding `entry` declared here
11 | tx.send(entry.file_name()).unwrap();
| --------^^^^^-------------
| | |
| | borrowed value does not live long enough
| argument requires that `entry` is borrowed for `'1`
12 | }
| - `entry` dropped here while still borrowed
What should I do? If it's impossible to solve due to being an ownership problem with messages and threads, what other alternatives should I try? I need to pass entry.file_name()
to the channel upon each iteration.
Upvotes: -1
Views: 84
Reputation: 21
Solved by appending .to_os_string()
to entry.file_name()
; that is, promote it from &OsStr
to OsString
. Turns out that you should send owned types instead of borrowed references in channels, for Sender
's lifetime depends on the type (?).
Upvotes: 1