Ржавчина: изменчиво заимствуйте себя внутри вложенных выражений соответствия

#rust #self #mutable #borrow-checker

Вопрос:

Я новичок в Rust и пытаюсь написать сканер для своего проекта. Однако у меня возникают проблемы с ошибками заимствования, которые я не знаю, как обойти. Вот мой код:

 pub fn read_next(amp;mut self) -> Option<Result<Token>> {
    match self.read_lookahead() {
        Some(tok) => Some(Ok(tok)),
        None => {
            match self.read_char() {
                Some(Ok(c)) => match c {
                    // TODO
                    _ => None
                }
                Some(Err(e)) => Some(Err(e)),
                None => None
            }
        }
    }
}
 

И вот подписи read_lookahead и read_char :

 fn read_lookahead(amp;mut self) -> Option<Token>

fn read_char(amp;mut self) -> Option<Result<char>>
 

Обе эти функции необходимо обновить self для правильной работы. Ошибка, которую я получаю, заключается в следующем:

 error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> srcsyntaxscan.rs:69:23
   |
65 |     pub fn read_next(amp;mut self) -> Option<Result<Token>> {
   |                      - let's call the lifetime of this reference `'1`
66 |         match self.read_lookahead() {
   |               ---- first mutable borrow occurs here
67 |             Some(tok) => Some(Ok(tok)),
   |                          ------------- returning this value requires that `*self` is borrowed for `'1`
68 |             None => {
69 |                 match self.read_char() {
   |                       ^^^^ second mutable borrow occurs here
 

Интуитивно я не совсем понимаю эту ошибку. Кажется, что self это просто последовательно заимствовано: read_lookahead не поддерживает ссылку self после ее завершения-следовательно, на самом деле одновременно сохраняется только одна изменяемая ссылка. Как я сообщу об этом компилятору?

Я предполагаю, что это требует некоторых хитростей с параметрами срока службы, но я не совсем уверен, как их указать, чтобы они работали — Я пробовал amp; использовать «mut self’ as parameter and having t» в качестве параметра времени жизни для всех моих функций, но это не сработало.

Для справки, self равно a Scanner<'a> , и возвращаемое Token значение также имеет параметрическое время жизни 'a . Может ли кто-нибудь объяснить мне, как обойти эту ошибку? Дайте мне знать, если вам потребуется дополнительная информация о моем коде. Спасибо!

Комментарии:

1. Там недостаточно кода/информации, чтобы воспроизвести проблему. Вот рабочая версия кода в Rust Playground. Вы можете изменить его, чтобы воспроизвести проблему.

2. @Todd Как мне изменить рабочую версию, чтобы воспроизвести проблему? (может быть, я просто слеп и упускаю что-то очевидное…)

3. Это тот же вопрос, который я задавал @tungli. Я создал игровую площадку для плаката, чтобы они могли изменить его и воспроизвести проблему, чтобы другие могли точно видеть, с чем они столкнулись. Там просто не хватало, чтобы пройти по коду, который был отправлен.

4. @Todd о, теперь я понимаю :-Д спасибо!

5. @Тодд Читает комментарий о сроках жизни, может быть, код выглядит так (ссылка на игровую площадку) ? Это действительно воспроизводит ошибку.