退出多个循环
本文关键字:循环 退出 | 更新日期: 2023-09-27 18:20:35
可能重复:
打破嵌套循环
我有这个代码
foreach (___)
{
foreach (___)
{
foreach (___)
{
if (condition)
{
//break out of all loops
}
}
}
}
但break
只"打破"了最核心的循环(对不起我的英语),我想把它们都留下。。。
我在想:
- GOTO,但我一直被告知不要使用它
- 一种布尔标志
还有什么更优雅的方式吗?像C#提供的那样?
提前感谢您的帮助!
一个非常优雅的解决方案是,当您想要中断所有循环时,将整个循环嵌套移动到一个单独的方法和return;
。
goto
在这里非常好:
foreach (___)
{
foreach (___)
{
if (condition)
{
goto done;
}
}
}
done: ;
最好的方法可能是用返回语句重构到更小的方法。但是,如果您在作用域中需要大量变量,则可以始终使用委托。
Action work = delegate
{
foreach (___)
{
foreach (___)
{
foreach (___)
{
if (condition)
{
return;
}
}
}
}
};
work();
几年前,当我还在学校的时候,我们和一个非常愚蠢的老师一起学习信息学。一条规则是"没有后藤"。我有一个带有多个循环的算法,在没有goto的情况下,循环的大小增加了很多倍。
有充分的理由,打破多个循环就是其中之一。
也许这是使用goto
的唯一有效原因。
bool bLoopBreak = false;
foreach (___)
{
foreach (___)
{
foreach (___)
{
if (condition)
{
bLoopBreak = true;
break;
//break out of all loops
}
}
if (bLoopBreak) break;
}
if (bLoopBreak) break;
}
在这种情况下不要害怕使用goto
。break
和continue
只是goto
的语法糖,而且注释谨慎且正确——它可以使代码比许多嵌套检查更清晰,以查看是否应该停止循环。
PHP可以让你做到这一点:
foreach (___)
{
foreach (___)
{
foreach (___)
{
break 3; // get out of all 3 loops
}
}
}
我对C#了解不多,但它可能有类似的功能。
只是在其中抛出一个替代方案:您也可以在循环中抛出一个异常。在C#/Java/Python中,这样做相当便宜。(在C++中,没有那么多。)
请注意,对于类似的情况,Python有一个StopIteration
异常,所以这并非闻所未闻,尽管它在C#中可能有点非正统。)
有时,您可以免费获得异常,因此可以使用它,但如果您采用这种方法,您最好将其记录下来。
try {
foreach (___) {
foreach (___) {
if(your condition true) {
throw new IterationDone(); // or use a singleton to avoid allocating
}
}
}
// not found
catch (IterationDone e) {
// yay
}
我把这个答案做成了一个社区维基,这样它就可以被看到和讨论了。(我不主张它是第一个也是最好的解决方案,它只是一个解决方案,因此值得在这里…)