Я создаю небольшое приложение Rust, используемое для составления статистики о программах и проектах. Моей первоначальной целью было сделать его универсальным, чтобы его можно было модифицировать и использовать в качестве библиотеки.
Для этого я создал структуру Processor
:
pub struct Processor {
handles: Vec<Box<dyn FileTypeHandle>>,
files_types: HashMap<String, Box<dyn FileType>>,
bytes_count: usize,
files_count: usize,
dirs_count: usize,
}
Что яhandle
является реализацией черты FileTypeHandle
, которая проверяет по расширению файла, может ли она с этим справиться. Если это возможно, файл обрабатывается им и создается статистика.
Во-вторых, file_types
- это реализации свойства FileType
, которые реализуют методы для записи окончательной статистики в консоль.
Давайтепредположим, что мой вектор handles
заполнен некоторыми дескрипторами.
Сначала мне нужно было реализовать функцию в Processor
для поиска в векторе handles
той, которая может обрабатывать расширение ext
:
pub fn handle_ext(&mut self, ext: &String) -> Option<&Box<dyn FileTypeHandle>> {
self.handles
.iter()
.find(move |handle: &&Box<dyn FileTypeHandle>| handle.can_handle(ext))
}
FileTypeHandle::can_handle
определяется как:
fn can_handle(&self, ext: &String) -> bool;
Я использую следующую функцию для получения типа файла в процессоре или создания по умолчанию:
pub fn get_file_type(&mut self, ext: &String) -> Option<&Box<dyn FileType>> {
if !self.files_types.contains_key(ext) {
let base = FileTypeBase::new(String::clone(ext));
if let Some(v) = self.handle_ext(ext) {
self.files_types.insert(String::clone(ext), v.handle(base));
}
}
self.files_types.get(ext)
}
Я думаю, вы понимаете, что я ожидаю от этого кода, но:
error[E0499]: cannot borrow `self.files_types` as mutable more than once at a time
--> src\processor.rs:61:17
|
59 | if let Some(v) = self.handle_ext(ext) {
| ---- first mutable borrow occurs here
60 |
61 | self.files_types.insert(String::clone(ext), v.handle(base));
| ^^^^^^^^^^^^^^^^ - first borrow later used here
| |
| second mutable borrow occurs here
Я прочитал много документации по Rust, включая официальную книгу, но я не знал, почемупроверка статической компиляции не удалась.
Хорошо, строка 61 использует self.file_types
, как сказано в сообщении об ошибке, но почему это второй заем ?! Первое подчеркнутое слово в строке 59 - это просто self
(или self.handle_ext
?), Которые не заимствуют self.file_types
.