我认为我没有借用变量的生命周期错误

时间:2018-12-09 05:17:12

标签: rust

我有一段代码,它递归地读取目录并为每个文件创建一个哈希。这是代码:

//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,我不认为我是借来的。
  • 我在其他任何地方都没有使用'e',那么编译器为什么要关心它?可以删除它。

最小,完整和可验证的示例:main.rs lib.rs

1 个答案:

答案 0 :(得分:3)

FileInfo包含对str的引用,而不是对拥有的String的引用。这意味着它只能生存到它引用的str为止。

您尝试通过克隆e.path().to_str()来避免该问题。这样,您将拥有一个不应以任何方式绑定到e的新副本。没错,但是因为克隆是在循环的迭代中创建的,所以它仅在循环的迭代中有效。

所以最后,克隆不会改变任何东西,因为生命周期仍然是相同的(您可以尝试一下)。

一种解决方案是修改FileInfo,使其包含String而不是&str。这样,每个FileInfo实例都可以自由移动,而不会影响生命周期。