Ошибка времени жизни для переменной, я думаю, что я не заимствую - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть блок кода, который рекурсивно читает каталог и создает хэш для каждого файла.Это код:

//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 голосов
/ 09 декабря 2018

FileInfo содержит ссылку на str, а не на String.Это означает, что он может жить только до тех пор, пока он ссылается на str.

Вы пытались избежать этой проблемы, клонируя e.path().to_str().Таким образом, у вас есть новая копия, которая никоим образом не должна быть связана с e.Это правильно, но поскольку клон был создан в итерации цикла, он живет только для этой итерации цикла.

Таким образом, в конце концов, клонирование ничего не меняет, поскольку время жизни все ещето же самое (Вы можете попробовать).

Одним из решений было бы изменить FileInfo так, чтобы он содержал String вместо &str.Таким образом, каждый экземпляр FileInfo может свободно перемещаться без жизненных конфликтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...