rust - while 循环推进迭代器 - 这是好的做法吗?

标签 rust iterator lexer

我正在从头开始用 Rust 编写一个自上而下的解析器,这就是我到目前为止所拥有的。

use std::str::Chars;

struct Lexer<'a> {
    peek: Option<char>,
    chars: Chars<'a>,
}

impl<'a> Lexer<'a> {
    fn new(string: &'a str) -> Self {
        let mut chars = string.chars();
        Self {
            peek: chars.next(),
            chars
        }
    }

    fn next(&mut self) -> Option<char> {
        let peek = self.peek;
        self.peek = self.chars.next();
        peek
    }

    fn peek(&self) -> Option<char> {
        self.peek
    }

    fn next_if<F>(&mut self, cond: F) -> Option<char> where
        F: FnOnce(char) -> bool {
    
        if cond(self.peek()?) {
            self.next()
        } else {
            None
        }
    }

    fn eat_while<F>(&mut self, cond: F) where
        F: FnOnce(char) -> bool {

        while self.next_if(cond).is_some() {}
    }
}

在这里你可以看到我的 eat_while 实现接受一个 lambda(称为 cond)并推进迭代器,直到指定的值与 cond 不匹配,或者 chars 迭代器为空。 因为 while 循环使迭代器前进,所以不需要循环体。然而,我被告知空 while 循环是不好的做法

我尝试的是在 eat_while 中重新创建“next_if”功能。
然而,这似乎是不可能的:

while cond(self.peek()).is_some()
// does not work

因为 self.peek() 返回一个选项,所以无法将其传递给 cond。
我尝试打开 self.peek():

while cond(self.peek().unwrap()).is_some()
// does not work

如果到达文件末尾,这会发生 panic ,所以它绝对不是一个选项。

最佳答案

在这种情况下,您可以使用Option::and_then:

while self.peek().and_then(|p| cond(p)).is_some() {/*...*/}

关于rust - while 循环推进迭代器 - 这是好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74782509/

相关文章:

rust - 使用#[serde(serialize_with…]和#[derive(Serialize)]不起作用

algorithm - 用于快速搜索由给定字母组成的单词的数据结构

rust - 为什么创建对取消引用的可变引用的可变引用有效?

rust - 如何让迭代器链执行for_each()并返回一个计数?

PHP 生成器返回类型

python - 在 tensorflow 中初始化一个基本的一次性迭代器

java - ANTLR4:上下文相关的空间?

rust - 是否可以在 Rust 中打印以千位分隔符格式化的数字?

autocomplete - python中自定义词法分析器上的QScintilla自动完成功能

antlr - 在 ANTLR 词法分析器规则中强制采用替代方案