Rust 如何打破生锈的do-while样式循环?
生锈允许一种边做边循环,例如: 所以C风格:Rust 如何打破生锈的do-while样式循环?,rust,Rust,生锈允许一种边做边循环,例如: 所以C风格: do { something(); } while (test()); 可以用锈迹书写为: while { something(); test() }{} while { if (something()) { break; } test() }{} 但是,在这种情况下使用break会出现问题: 这就是C风格: do { if (something()) {
do {
something();
} while (test());
可以用锈迹书写为:
while {
something();
test()
}{}
while {
if (something()) {
break;
}
test()
}{}
但是,在这种情况下使用break会出现问题:
这就是C风格:
do {
if (something()) {
break;
}
} while (test());
不能用锈迹书写为:
while {
something();
test()
}{}
while {
if (something()) {
break;
}
test()
}{}
无法使用编译,无法在循环外部中断
有没有办法打破这种形式的while循环
注意1)使用:
do{…}while test()
流控制而不是
while test(){…}
的原因是在这种情况下,当最初进入循环时test()
将为false
注意2)当使用而{…}
流控制时:在代码主体中调用continue
将跳过结尾处的break
检查
请参阅相关问题:您想得太多了
让我们构建一个真值表:
+-------------+--------+--------+
|某物()|测试()|结果|
+-------------+--------+--------+
|对|对|停|
+-------------+--------+--------+
|对|错|停|
+-------------+--------+--------+
|假|真|继续|
+-------------+--------+--------+
|假|假|停|
+-------------+--------+--------+
因此,这可以写成:
while !something() && test {}
没有必要使用中断
正如注释中所述,了解此模式的工作原理非常重要。它不是的一种特殊形式,而,它只是滥用循环测试来完成通常在体内完成的事情。由于break
和continue
不属于循环测试(除非循环是另一个循环的一部分,在这种情况下,它们将编译,但会中断/继续外部循环),Rust拒绝它们
使用上述模式模拟break
的一种简单方法是将测试代码移动到一个闭包中,可以使用return
退出该闭包:
while (|| {
if something() {
return false // break
}
test()
})() {}
continue
可以通过相同的方式进行模拟,只需从闭包返回true
如果将其表示为宏,可能会使意图更清楚。为什么不循环{/*code*/if test(){break;}}
?我不得不说,我认为这是一个可怕的黑客()。第一组大括号实际上不是while循环体-它们是条件,这就是为什么不能中断<代码>虽然{break}{}
没有任何意义,这就是为什么这种语法可能弊大于利。@Aurora0001一个人的黑客行为是另一个人的模式。:)我在各种缺少本地do-while(例如Emacs Lisp)的Lisp方言中看到过这种风格,一旦你习惯了,它就可以阅读了。我同意,一旦需要break
和continue
时,切换到带有自定义设置的中断逻辑的loop
可能是一个更好的主意。@user4815162342,也许是这样,但在我看来,最好是“防御性的”,并假设读代码的程序员不如你聪明,而且不会注意到这种模式。如果没有人指出和思考,我肯定不会知道发生了什么。@Aurora0001我同意防御——正如他们所说,“编写代码时,就像下一个维护者是一个知道你住在哪里的疯子一样。”另一方面,一些非常有用的习语在第一次遇到时看起来像垃圾,但人们会学会识别,使用,甚至在一段时间后欣赏它们。(Rust有很多一开始看起来很奇怪的功能,比如使用;
来确定是否返回值。)Rust仍然是一种年轻的语言,还有待观察哪些模式会被社区认为是足够有用的,从而被认为是惯用语。我不能使用这种逻辑的原因是test
在第一次进入循环时是错误的,在问题中作为注释补充了这一点。