开发人员是否应该避免在 C# 中使用continue或其他语言中的等价物来强制循环的下一次迭代?支持或反对的论点是否会与有关Goto的论点重叠?
17 回答
我认为应该更多地使用continue!
我经常遇到如下代码:
for (...)
{
if (!cond1)
{
if (!cond2)
{
... highly indented lines ...
}
}
}
代替
for (...)
{
if (cond1 || cond2)
{
continue;
}
...
}
使用它使代码更具可读性!
continue
比说,更有害吗break
?
如果有的话,在我遇到/使用它的大多数情况下,我发现它使代码更清晰,不像意大利面条。
你可以写好代码有或没有继续,你可以写坏代码有或没有继续。
关于 goto 的参数可能有一些重叠,但就我而言,使用 continue 相当于使用 break 语句(在循环中)或从方法体中的任何位置返回语句 - 如果使用正确,它可以简化代码(不太可能包含错误,更易于维护)。
没有有害的关键字。它们只有有害用途。
Goto 本身并无害,继续也无害。它们需要小心使用,仅此而已。
如果 continue 导致可读性问题,那么您可能还有其他问题。例如,for 循环中的大量代码。如果您必须编写大型 for 循环,我会尝试坚持在 for 循环顶部附近使用 continue 。否则,很容易错过深埋在 for 循环中间的 continue。
我喜欢在循环的开头使用 continue 来处理简单的 if 条件。
对我来说,它使代码更具可读性,因为没有额外的嵌套,您可以看到我已经明确处理了这些情况。
这与我使用 goto 的原因相同吗?也许。我有时确实使用它们来提高可读性并停止代码的嵌套,但我通常更多地使用它们来进行清理/错误处理。
我会说:“这取决于”。
如果您有相当小的循环代码(您可以在不滚动的情况下看到整个循环代码),通常可以使用 continue。
但是,如果循环体很大(例如由于一个大开关),并且有一些后续代码(比如在开关下方),您可能会通过添加 continue 来轻松引入错误,从而有时会跳过该代码。我在字节码解释器的核心遇到过这种情况,在某些情况下,由于在某些情况下分支的继续,有时无法执行某些检测代码。
这可能是一个人为构造的案例,但我通常会尽量避免 continue 并使用 if (但不会像 Rob 的示例代码那样嵌套太深)。
我认为 continue 永远不会像 goto 那样困难,因为 continue 永远不会将执行移出它所在的代码块。
如果您正在遍历任何类型的结果集,并对所述结果执行操作,例如在 for each 中,并且如果一个特定结果导致问题,则它在捕获预期错误(通过 try-catch)方面非常有用,记录它,然后通过 continue 转到下一个结果。imo,对于在奇数时间执行工作的无人值守服务,Continue 特别有用,并且一个异常不应影响其他 x 条记录。
就这个程序员而言,嵌套 if/else被认为是有害的。
在循环的开头使用 continue 来避免迭代不必要的元素是无害的,并且非常有用,但是在嵌套的 if 和 else 中间使用它可以将循环代码变成一个复杂的迷宫,以便理解和验证。
我认为它的使用避免也是语义误解的结果。从未在他们的代码上看到/写过“继续”关键字的人,当看到带有 continue 的代码时,可以将其解释为“自然流的延续”。例如,如果不是 continue 我们有next,我想更多的人会喜欢这个有价值的光标功能。
goto 可以用作继续,但不能反过来。
您可以“转到”任何地方,从而任意中断流量控制。
因此继续,几乎没有那么有害。
其他人已经暗示过......但是 continue 和 break 由编译器强制执行,并且有自己的关联规则。Goto 没有这样的限制,尽管在某些情况下净效果可能几乎相同。
我不认为 continue 或 break 本身是有害的,尽管我确信两者都可以以一种会使任何理智的程序员作呕的方式使用不当。
在大多数语言中,Continue 是一个非常有用的功能,因为它允许在某些条件下跳过代码块。
一种替代方法是在 if 语句中使用布尔变量,但每次使用后都需要重置这些变量。
我会说是的。对我来说,它只是打破了流畅编写的代码的“流程”。
另一个论点也可能是,如果您坚持大多数现代语言支持的基本关键字,那么您的程序流(如果不是逻辑或代码)可以移植到任何其他语言。使用不受支持的关键字(即 continue 或 goto)会破坏这一点。
这实际上更像是个人喜好,但我从来没有使用过它,并且在我编写新代码时也没有真正考虑过它。(与 goto 相同。)
continue
我觉得不对。break
让你离开那里,但continue
似乎只是意大利面。
另一方面,您可以continue
使用break
(至少在 Java 中)进行模拟。
for (String str : strs) contLp: {
...
break contLp;
...
}
break
(这篇文章在上述代码中存在十多年的明显错误。这对于/看起来不太好continue
。)
continue
在某些情况下可能有用,但我仍然觉得它很脏。可能是时候引入一种新方法了。
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 ...
}
这些用途应该很少见。
我相信反对 continue 的底线论点是它更难证明代码是正确的。这是数学意义上的证明。但这对您来说可能无关紧要,因为没有人有资源“证明”一个非常复杂的计算机程序。
输入静态分析工具。你可能会让他们更难...
还有 goto,出于同样的原因,这听起来像是一场噩梦,但在代码中的任何随机位置。