我有一段代码,它递归地读取目录并为每个文件创建一个哈希。这是代码:
//read the file paths all the way upto individual files
for dir in search_dirs.iter(){
//read the dir, skip errors (hidden files, syslinks etc)
for e in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
//check if it's a file, continue
if metadata(e.path().display().to_string()).unwrap().is_file(){
//"clone" std::path::Path as &str
let file_path = e.path().to_str().unwrap().clone();
//create a new FileInfo Object
let mut file_obj = FileInfo::new(None, None, file_path);
file_obj.generate_hash();
file_obj.generate_path_hash();
//count the num for each file content hash ~ HashMap
*file_counter.entry( file_obj.get_hash() ).or_insert(0) += 1;
//HashMap for file path hash and FileInfo Object
/*If I add this statement I have an Error: E0597
file_info.entry(file_obj.get_path_hash())
.or_insert(file_obj.clone());
*/
}
}
}
如果我添加file_info.entry(file_obj.get_path_hash()).or_insert(file_obj.clone())
,则会收到错误消息E0597
。
error[E0597]: `e` does not live long enough
--> src/main.rs:41:33
|
41 | let file_path = e.path().to_str().unwrap().clone();
| ^ borrowed value does not live long enough
...
48 | file_info.entry(file_obj.get_path_hash() ).or_insert(file_obj.clone());
| --------- borrow used here, in later iteration of loop
49 | }
50 | }
| - `e` dropped here while still borrowed
问题
e
,我不认为我是借来的。答案 0 :(得分:3)
FileInfo
包含对str
的引用,而不是对拥有的String
的引用。这意味着它只能生存到它引用的str
为止。
您尝试通过克隆e.path().to_str()
来避免该问题。这样,您将拥有一个不应以任何方式绑定到e
的新副本。没错,但是因为克隆是在循环的迭代中创建的,所以它仅在循环的迭代中有效。
所以最后,克隆不会改变任何东西,因为生命周期仍然是相同的(您可以尝试一下)。
一种解决方案是修改FileInfo
,使其包含String
而不是&str
。这样,每个FileInfo
实例都可以自由移动,而不会影响生命周期。