关于不可知的语言:继续被认为有害吗?

关于不可知的语言:继续被认为有害吗?

Continue Considered Harmful?

开发人员是否应该避免使用C#或其他语言的等效代码continue来强制循环的下一次迭代? 支持或反对论点是否与有关Goto的论点重叠?


我认为应该更多地使用continue!

我经常遇到如下代码:

1
2
3
4
5
6
7
8
9
10
for (...)
{
   if (!cond1)
   {
      if (!cond2)
      {
          ... highly indented lines ...
      }
   }
}

代替

1
2
3
4
5
6
7
8
9
for (...)
{
   if (cond1 || cond2)
   {
      continue;
   }

   ...
}

使用它可以使代码更具可读性!


continue是否比break有害?

如果有的话,在我遇到/使用它的大多数情况下,我发现它使代码更清晰,更像意大利面条。


您可以在继续或不继续的情况下编写好的代码,并且可以在继续或不进行的情况下编写错误的代码。

关于goto的参数可能有一些重叠,但是就我而言,继续使用的用法等同于在方法体中的任何位置使用break语句(循环)或return语句-如果正确使用,则可以简化代码(不太可能包含错误,更易于维护)。


没有有害的关键字。它们只有有害用途。

Goto本质上是无害的,也不会继续。它们需要小心使用,仅此而已。


我喜欢在循环开始时使用Continue来处理简单的if条件。

对我来说,由于没有多余的嵌套,它使代码更具可读性,并且您可以看到我已明确处理了这些情况。

这与我使用goto的原因相同吗?也许。我有时会使用它们来提高可读性并停止代码的嵌套,但是通常我会更多地使用它们来进行清理/错误处理。


如果继续导致可读性问题,则可能还有其他问题。例如,for循环内有大量代码。如果您必须编写较大的for循环,我会尽量坚持在for循环顶部附近继续使用。否则,很容易错过在for循环中间深处连续的内容。


我会说:"取决于"。

如果您的循环代码很小(在不滚动的情况下可以看到整个循环代码),通常可以使用继续。

但是,如果循环体很大(例如,由于开关较大),并且有一些后续代码(例如,在开关下方),则可以通过添加继续并有时跳过该代码来轻松引入错误。我在字节码解释器的心脏中遇到过这种情况,由于某些情况下分支继续执行,因此有时未执行某些检测代码。

这可能是一个人为构造的情况,但是我通常尝试避免继续并使用一个if(但嵌套不要像Rob的示例代码中那样深)。


  • 在循环开始时使用continue避免不必要元素上的迭代是无害的,并且可能非常有用,但是在嵌套的ifs和else中间使用它可以将循环代码变成复杂的迷宫,以进行理解和验证。

  • 我认为避免用法也是语义误解的结果。从未在代码上看到/写入" continue"关键字的人,看到带有continue的代码时,可以将其解释为"自然流的延续"。例如,如果不是继续,我们下一步是,我认为更多的人会喜欢这种有价值的光标功能。


  • 我认为continue不会像goto那样困难,因为continue不会将执行移出它所在的代码块。


    如果您要遍历任何类型的结果集,并对每个结果进行操作(例如,在每个结果中),并且如果某个特定结果引起了问题,则它对于捕获预期的错误(通过try-catch)非常有用,记录它,并通过继续前进到下一个结果。对于在零时执行作业的无人值守服务,继续(imo)尤其有用,并且一个例外不应影响其他x个记录。


    就此程序员而言,嵌套if / else被认为是有害的。


    其他人对此有所暗示...但是继续和中断是由编译器强制执行的,并具有自己的关联规则。尽管在某些情况下最终效果可能几乎相同,但Goto没有这种限制。

    我不认为继续或中断本身是有害的,尽管我敢肯定,任何一种使用都可能使任何理性的程序员感到困惑的方式都不能很好地使用。


    goto可以用作继续,但不能相反。

    您可以在任何地方"转到",从而任意中断流量控制。

    因此继续下去,没有那么有害。


    我会说是的。对我来说,这只是打破了流畅编写代码的"流程"。

    另一个论点也可能是,如果您坚持大多数现代语言支持的基本关键字,那么您的程序流程(如果不是逻辑或代码)可以移植到任何其他语言。使用不受支持的关键字(例如,continue或goto)会破坏这一点。

    实际上,这更多是个人喜好,但是在编写新代码时,我从来没有使用过它,也没有真正将其视为一种选择。 (与goto相同。)


    在大多数语言中,Continue是一个非常有用的功能,因为它允许在某些情况下跳过代码块。

    一种替代方法是在if语句中使用布尔变量,但是每次使用后都需要将其重置。


    我相信反对continue的底线论点是,它更难证明代码是正确的。这是从数学意义上证明的。但这对您可能并不重要,因为没有人拥有"证明"非常复杂的计算机程序的资源。

    输入静态分析工具。您可能会使事情变得更艰难...

    和goto一样,出于相同的原因,这听起来像是一场噩梦,但在代码中的任何随机位置。


    continue对我来说是错的。 break带您离开那里,但continue似乎只是意大利面。

    另一方面,可以用break模拟continue(至少在Java中)。

    1
    2
    3
    4
    5
    for (String str : strs) contLp: {
        ...
           break contLp;
        ...
    }

    (此发布在上面的代码中有一个明显的错误已有十多年了。对于break / continue而言,这看起来并不好。)

    continue在某些情况下可能有用,但对我来说仍然很脏。现在可能是时候介绍一种新方法了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (char c : cs) {
        final int i;
        if ('0' <= c && c <= '9') {
            i = c - '0';
        } else if ('a' <= c && c <= 'z') {
            i = c - 'a' + 10;
        } else {
            continue;
        }
        ... use i ...
    }

    这些用途应该很少见。


    推荐阅读