如何在Rust中打破做时风格循环?

How to break out of a do-while style loop in Rust?

Rust允许一种do-while循环,例如:

所以C风格:

1
2
3
do {
    something();
} while (test());

可以用Rust编写为:

1
2
3
4
while {
    something();
    test()
}{}

但是,在这种情况下使用break会有一个问题:

所以这个C风格:

1
2
3
4
5
do {
    if (something()) {
        break;
    }
} while (test());

不能用Rust编写为:

1
2
3
4
5
6
while {
    if (something()) {
        break;
    }
    test()
}{}

无法使用cannot break outside of a loop进行编译。

有没有办法打破这种形式的while循环?

注1)使用原因:do {...} while test()代替while test() {...}的是流量控制,在这种情况下,test()在最初进入循环时将是false

注2)使用while {...}流控制时:在代码正文中调用continue将跳过最后的break检查。

请参阅相关问题:如何在宏中包装do-while样式循环,以保持连续流控制?


如评论中所述,了解此模式的工作原理很重要。 它不是while的特殊形式,它只是滥用循环测试来完成通常在体内完成的事情。 由于breakcontinue不属于循环测试(除非该循环是另一个循环的一部分,在这种情况下它们将进行编译,但会中断/继续外部循环),因此Rust拒绝了它们。

用上述模式模拟break的一种直接方法是将测试代码移到一个可以用return退出的闭包中:

1
2
3
4
5
6
while (|| {
    if something() {
        return false // break
    }
    test()
})() {}

可以通过相同的方式模拟continue,只需从闭包中返回true

如果将其表示为宏,则可能可以使意图更清晰。


您想得太多了。

让我们建立一个真值表:

1
2
3
4
5
6
7
8
9
10
11
+-------------+--------+--------+
| something() | test() | Result |
+-------------+--------+--------+
|    true     |  true  |  stop  |
+-------------+--------+--------+
|    true     |  false |  stop  |
+-------------+--------+--------+
|    false    |  true  |  go on |
+-------------+--------+--------+
|    false    |  false |  stop  |
+-------------+--------+--------+

因此,可以这样写:

1
while !something() && test {}

不需要break