Я уже давно атаковал эту проблему, но боюсь, что, возможно, я ударил стену.
У меня есть черта Quiz
, которая содержит, что позволяет вам установить вопрос. Эти вопросы существуют в пуле вопросов (Vec
), который находится в сфере действия так же долго, как и Викторина. Моя первая попытка была такой:
pub trait Quiz {
fn set_question(&mut self, q: &mut Question);
...
}
На этом этапе функция, использующая эту черту, успешно компилировалась:
pub fn next(&mut self) -> Option<&Box<dyn Quiz>> {
let mut question = self.questions.choose_mut(&mut self.rng)?;
let mut quiz = self
.quizzes
.iter_mut()
.filter(|qz| qz.is_applicable(question))
.choose(&mut self.rng)?;
quiz.set_question(question);
quiz.set_context(&self.questions);
Some(quiz)
}
К сожалению, я считаю, что моя первоначальная реализация черты была ошибочной. Я не смог реализовать set_question
, потому что не было гарантии, что ссылка q
будет существовать столько же, сколько и self
, в которой она хранится. Чтобы исправить это, я добавил несколько явных времен жизни:
pub trait Quiz<'a> {
fn set_question(&'a mut self, q: &'a mut Question);
...
}
Это означало, что мне нужно было изменить мою функцию next
на следующую:
pub fn next(&'a mut self) -> Option<&Box<dyn Quiz<'a>>> {
let mut question = self.questions.choose_mut(&mut self.rng)?;
let mut quiz = self
.quizzes
.iter_mut()
.filter(|qz| qz.is_applicable(question))
.choose(&mut self.rng)?;
quiz.set_question(question);
quiz.set_context(&self.questions);
Some(quiz)
}
К сожалению, это приводит к появлению 3 ошибок проверки заимствования, которых раньше не было. Все три, кажется, проистекают из того факта, что set_question
и set_context
не освобождают свои заимствования (даже если они не возвращают никакой стоимости). Например:
error[E0502]: cannot borrow `*quiz` as immutable because it is also borrowed as mutable
--> src/core/quiz.rs:37:14
|
12 | impl<'a> QuizDispatcher<'a> {
| -- lifetime `'a` defined here
...
35 | quiz.set_question(question);
| ---- mutable borrow occurs here
36 | quiz.set_context(&self.questions);
37 | Some(quiz)
| -----^^^^-
| | |
| | immutable borrow occurs here
| returning this value requires that `**quiz` is borrowed for `'a`
Где QuizDispatcher
- это структура, содержащая вопросы и тесты для заполнения:
pub struct QuizDispatcher<'a> {
questions: &'a mut [Question],
quizzes: &'a mut [Box<dyn Quiz<'a>>],
...
}
Я немного озадачен этим, хотя я Я уверен, что мне просто не хватает чего-то простого ...