我正在尝试制作一个适用于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!");
}
上面的代码导致错误:
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
将在下一次循环迭代之前被新值覆盖。
我犯了更大的错误吗?如何让编译器知道流中的可变借位已经完成,并且允许其他可变借位是安全的?