是否可以在`while let`中使用模式匹配守卫?

问题描述 投票:0回答:3

我有一个

while let
循环,它遍历
Result
的迭代器并使用模式匹配;它会遍历迭代器,直到遇到
Err
Ok
的值为空字符串:

while let Some(Ok(a)) = some_iterator.next() {
    if a == "" {
        break;
    }
    // ...
}

这段代码运行良好。然而,我认为

if
语句看起来很难看,并且可能不是惯用的 Rust。在
match
语句中,守卫可以用于模式匹配,如下所示:

match foo {
    Some(Ok(a)) if a != "" => bar(a)
    // ...
}

这对于我的

while let
循环来说是理想的选择,尽管那里使用的模式匹配似乎不支持它,导致语法错误:

while let Some(Ok(a)) = some_iterator.next() if a != "" { // <-- Syntax error
    // ...
}

while let
的情况下有没有办法使用这样的守卫?如果没有,如果找到空字符串,是否有更好的方法来跳出循环?

while-loop pattern-matching rust
3个回答
19
投票

不可以,

while let
if let
模式不能有防护装置。已经有一些关于改变这一点的讨论(例如here),但尚未做出任何决定。

关于替代方案,我认为你的版本非常清楚,我想不出任何方法可以真正改进它。


2
投票

对于那些从网络搜索中找到此内容的人,这里有

if-let-chains
RFC,它解决了
if let
表达式中的条件:

https://rust-lang.github.io/rfcs/2497-if-let-chains.html


0
投票

无论出于何种意图和目的,您的代码都是最清晰的。

但是您可以发挥创意(包括使用在询问时不可用的工具)。

将条件塞入模式匹配中:

while let (Some(a), true) = (iterator.next(), independent_condition()) {
    //do stuff
}

将过滤器放入迭代器中:

while let Some(a) = iterator.take_while(|a| a!= "").next() {
    //do stuff
}

请记住,在简单的情况下,当您最终得到一个迭代器时,您不再需要模式解构:

for a in iterator.take_while(|a| a!= "") {
    //do stuff
}

skip_while 和 scan 是迭代器上类似的高级方法,在这种情况下可能会派上用场。

© www.soinside.com 2019 - 2024. All rights reserved.