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

时间:2015-02-28 22:45:43

标签: ada

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

有没有办法可以做到这一点?

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

4 个答案:

答案 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中做了太多而且需要使用函数/过程。