Rust中用空while循环推进迭代器是否为良好编码实践?
Rust自顶向下解析器中
eat_while空while循环的实践疑问与优化 首先明确:你当前用的空while循环本身不算不良实践——它的逻辑通顺,通过重复调用next_if直到返回None完成字符的持续消耗。但从可读性角度确实可以优化得更直观,而且你的代码还存在一个隐藏的编译问题需要先修正。
先解决隐藏的闭包约束错误
你当前的next_if和eat_while使用了FnOnce(char) -> bool的约束,这会导致编译失败:FnOnce意味着闭包只能被调用一次,而eat_while的循环会多次调用next_if,第一次调用就会消耗掉闭包,后续循环会因闭包已被移动而报错。
需要把约束改成Fn(char) -> bool(如果闭包不需要修改内部状态)或者FnMut(char) -> bool(如果闭包需要修改自身状态),示例:
fn next_if<F>(&mut self, cond: F) -> Option<char> where F: Fn(char) -> bool { if let Some(c) = self.peek() { if cond(c) { self.next() } else { None } } else { None } }
优化eat_while的实现(替代空while循环)
如果你觉得空while循环不够直观,可以改用loop配合模式匹配,逻辑更清晰:
fn eat_while<F>(&mut self, cond: F) where F: Fn(char) -> bool { loop { match self.peek() { // 字符存在且满足条件,推进迭代器 Some(c) if cond(c) => { self.next(); } // 字符不存在或不满足条件,退出循环 _ => break, } } }
如果想保留next_if的复用,也可以调整闭包传递方式(避免消耗闭包),同时让循环更显式:
fn eat_while<F>(&mut self, cond: F) where F: Fn(char) -> bool { while let Some(_) = self.next_if(&cond) { // 无需额外逻辑,仅循环直到next_if返回None } }
这里用while let替代while ...is_some(),可读性会稍好一些。
回到空while循环的实践问题
空while循环本身没有语法或逻辑错误,在Rust社区中也偶尔能看到类似写法,但它的缺点是不够直观——初次阅读代码的人需要反应一下循环体为空的意图。如果团队或个人代码风格更倾向于显式表达逻辑,那么改用loop或while let的写法会更友好。
内容的提问来源于stack exchange,提问作者John doe
相关产品推荐
相关产品推荐

