我希望有一个无限循环,其中循环几乎遍及整个程序,并且在任何时候,基于条件语句,我希望它退出循环的特定迭代并返回到顶部并执行。
有没有办法可以做到这一点?
它不一定是无限循环;它可以是for循环。我只是想让它进入该循环的下一次迭代。
答案 0 :(得分:4)
Ada没有continue
的等价物。完成同样事情的最简单方法可能只是将循环的其余部分放在if
语句中。所以不是这样的事情(这里是我们处理输入行并跳过那些以#开头的例子):
while not End_Of_File (Input_File) loop
...
Read_A_Line (Input_File, Line);
if Line(Line'First) = "#" then
continue; -- ERROR--Ada doesn't have a continue statement
end if;
... process the input line
end loop;
你可以说
while not End_Of_File (Input_File) loop
...
Read_A_Line (Input_File, Line);
if Line(Line'First) /= "#" then
... process the input line
end if;
end loop;
如果它变得复杂,您可能想要定义布尔Need_To_Keep_Processing_Line
或其他东西。如果您有几个点需要等同于continue
,那么最终可能会得到一个乘法嵌套if
;如果这太难看了,那么我有时会做的一件事就是在同一个布尔上有多个非嵌套的if
:
if Need_To_Keep_Processing_Line then
...
if something then
if something-else then
Need_To_Keep_Processing_Line := false;
end if;
end if;
end if;
if Need_To_Keep_Processing_Line then -- again
...
end if;
提到了其他替代方案:(1)goto
; (2)从各个方面使用程序和return
; (3)例外。例外有两个问题:首先,这不是一个例外,因此您将构造用于其目的并非预期,可能会使您的代码不易被读取;并且异常是低效的(一些编译器在输入具有异常处理程序的块时添加额外的代码;其他编译器通过在编译时设置表来避免这种情况,但是当引发异常时需要表搜索)。使用过程可能是可行的,这取决于循环体是否代表易于命名和识别的概念。如果它不是,那么提取循环体可能会妨碍可读性,因为您正在添加一个并不真正具有"过程的程序"目的。避免使用goto
的原因是,在我们曾经不加选择地使用它的70年代,导致了大量纠结的代码。尽管您可能已经听说过它,但如果以严格的方式使用它,则不必使代码不可读。我一般不会使用它。但是如果使用C风格的语言进行编程,我也会避免使用continue
,因为对我而言,它只是一个美化的,并且#34; goto"没有在你的功能结束时有一个可见的标签的好处,提醒你有人是"去"那里。
但我对此的真实感觉是,如果使用if
导致丑陋的代码,那么你的循环体可能太大了,无论如何都需要分解。解决方案不是要恢复到其他解决方案之一(例外或goto
),而是找出使循环体更小且更易读的最佳方法。
答案 1 :(得分:3)
提出你在循环体中处理的异常:
procedure Main is
Try_Again: exception;
begin
while Keep_Going loop
begin
-- lots of stuff
if Give_Up_On_This_Iteration then
raise Try_Again;
end if;
-- lots more stuff
exception
when Try_Again =>
null;
end;
end loop;
end Main;
答案 2 :(得分:1)
您可以使用goto语句
答案 3 :(得分:0)
要回答你的问题,我所知道的最简单的方法(语法方面)是使用另一个循环,嵌套在第一个循环中。退出内部循环会模仿continue语句。
loop
loop
...
exit when Some_Condition;
...
end loop;
end loop;
那就是说,如果你需要做那样的话,那些东西闻起来很糟糕。我个人使用了ajb在他的答案的开头所展示的内容,即使用if语句。如果if语句的嵌套级别太深,那么你可能在main中做了太多而且需要使用函数/过程。