Добавление времени жизни к признаку нарушает ранее скомпилированную функцию - PullRequest
0 голосов
/ 11 апреля 2020

Я уже давно атаковал эту проблему, но боюсь, что, возможно, я ударил стену.

У меня есть черта 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>>],
    ...
}

Я немного озадачен этим, хотя я Я уверен, что мне просто не хватает чего-то простого ...

...