如何在不违反借用规则的情况下包装可窥视的迭代器

时间:2018-07-29 04:19:43

标签: rust lifetime borrow-checker

我正在尝试制作一个适用于Peekable迭代器的简单词法分析器。当没有更多的字符要迭代时,我返回EOF而不是使用unwrap_or()

我有一个函数iter.peek().unwrap_or(&EOF),而不是经常输入peek_or_eof。我尝试使用如下功能:

use std::iter::Peekable;

const EOF: char = '\0';

enum Token {
    Identifier(String),
}

pub struct Lexer<I>
where
    I: Iterator<Item = char>,
{
    stream: Peekable<I>,
}

impl<I> Lexer<I>
where
    I: Iterator<Item = char>,
{
    fn peek_or_eof(stream: &mut Peekable<I>) -> &char {
        stream.peek().unwrap_or(&EOF)
    }

    fn read_identifier(stream: &mut Peekable<I>) -> Option<Token> {
        // ...

        let mut identifier = String::new();

        let mut next = Lexer::peek_or_eof(stream);
        while next.is_alphanumeric() || next == &'_' {
            identifier.push(stream.next().unwrap());
            next = Lexer::peek_or_eof(stream);
        }

        // ...
        None
    }
}

fn main() {
    println!("Hello, world!");
}

playground

上面的代码导致错误:

error[E0499]: cannot borrow `*stream` as mutable more than once at a time
  --> src/main.rs:31:29
   |
29 |         let mut next = Lexer::peek_or_eof(stream);
   |                                           ------ first mutable borrow occurs here
30 |         while next.is_alphanumeric() || next == &'_' {
31 |             identifier.push(stream.next().unwrap());
   |                             ^^^^^^ second mutable borrow occurs here
...
37 |     }
   |     - first borrow ends here

如果我理解正确,则借入生存期与返回的字符引用相同,本例中为next。但是,在检查while循环中的条件之后,我实际上并没有使用next,并且next将在下一次循环迭代之前被新值覆盖。

我犯了更大的错误吗?如何让编译器知道流中的可变借位已经完成,并且允许其他可变借位是安全的?

0 个答案:

没有答案