在 Ada 中立即开始循环的下一次迭代

5 ada

我想要一个无限循环,其中循环几乎贯穿整个程序,并且在任何时候,基于条件语句,我希望它退出循环的特定迭代并返回到顶部并执行。

有办法做到这一点吗?

它不必是无限循环;它可以是一个for循环。我只想让它进入该循环的下一次迭代。

小智 5

您可以使用 goto 语句

  • 我想说,模拟“Continue”是使用“goto”的合理情况。在这种情况下,我至少更喜欢“goto”而不是例外。 (4认同)

ajb*_*ajb 5

Ada 没有相当于 a 的东西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;
Run Code Online (Sandbox Code Playgroud)

你可以说

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;
Run Code Online (Sandbox Code Playgroud)

如果它变得复杂,您可能需要定义一个布尔值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;
Run Code Online (Sandbox Code Playgroud)

已经提到了其他替代方案:(1)goto;(2)使用程序并return从不同的角度进行;(3)例外情况。异常有两个问题:首先,这并不是真正的异常,因此您将构造用于非预期目的,可能会降低代码的可读性;并且异常效率低下(一些编译器在输入带有异常处理程序的块时添加额外的代码;其他编译器通过在编译时设置表来避免这种情况,但在引发异常时需要进行表搜索)。使用过程可能是可行的,具体取决于循环体是否表示易于命名和识别的概念。如果不是,那么提取循环体可能会妨碍可读性,因为您添加的过程实际上并没有“过程”目的。要避免的原因goto是,早在 70 年代,我们就曾经不加区别地使用它,导致出现大量错综复杂的代码。尽管您可能听说过它,但如果以规范的方式使用它并不一定会使代码变得不可读。我一般不使用它。但我也避免continue使用 C 风格语言进行编程,因为对我来说,这只是一个美化的“goto”,而没有在函数末尾有一个可见标签来提醒您有人“要去”那里的事实。

但我对此的真实感受是,如果使用if导致丑陋的代码,则您的循环体可能太大并且无论如何都需要分解。解决方案不是恢复到其他解决方案之一(异常 或goto),而是找出使循环体更小且更具可读性的最佳方法。