rust - 如何在不破坏借用规则的情况下包装可窥视的迭代器
问题描述
我正在尝试制作一个适用于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
会在循环的下一次迭代之前被新值覆盖。
我犯了更大的错误吗?如何让编译器知道流上的可变借用已完成并且允许另一个可变借用是安全的?
解决方案
推荐阅读
- python - python beautifulsoup 下一页
- c# - 我们可以避免在 C# 8.0 中使用不可为空的方法参数的空参数保护子句吗?
- pandas - 通过将行与另一个数据框匹配来查找列值的 pandas df
- javascript - 调用计算机视觉 OCR 时出现 415 错误
- c# - 静态类和 COM 互操作
- python - 将数据框中的系列中的多空间替换为单个空间并将其返回到系列
- c# - 如何计算 mongo 集合中具有相交子集合的项目?
- postgresql - PostgreSQL V12 创建临时表共享内存不足,我可以在磁盘上创建吗?
- python-3.x - 你怎么能用python写呢?
- python - 将每行的第 10 个索引乘以 2