首页 文章

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

提问于
浏览
0

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

//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

Question

  • 我克隆了 e ,我不认为我借了它 .

  • 我'm not using ' e`在其他任何地方,那么编译器为什么要关心呢?它可以被删除 .

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

1 回答

  • 3

    FileInfo 包含对 str 的引用,而不是 String . 这意味着它只能与它引用的 str 一样长 .

    您试图通过克隆 e.path().to_str() 来避免该问题 . 这样,您就有了一个不应该以任何方式绑定到 e 的新副本 . 这是正确的,但因为克隆是在循环的迭代中创建的,所以它只适用于循环的迭代 .

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

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

相关问题