我已经用Java编程好几年了,但我最近才回到学校获得一个正式学位。我很惊讶地发现,在我的上一个作业中,我因为使用下面这样的循环而失分。

do{
     //get some input.
     //if the input meets my conditions, break;
     //Otherwise ask again.
} while(true)

现在对于我的测试,我只是扫描一些控制台输入,但我被告知这种循环是不鼓励的,因为使用break类似于goto,我们只是不这样做。

我完全理解goto和它的Java兄弟break:label的陷阱,而且我很明智地不使用它们。我也意识到,一个更完整的程序会提供一些其他的逃避方式,比如结束程序,但我的教授并没有提到这一点,所以……

do-while(正确)怎么了?


当前回答

我想没什么,真的。老师们对goto过敏,因为他们听说那里很糟糕。否则你可以这样写:

bool guard = true;
do
{
   getInput();
   if (something)
     guard = false;
} while (guard)

这几乎是一样的。

也许这样更简洁(因为所有循环信息都包含在块的顶部):

for (bool endLoop = false; !endLoop;)
{

}

其他回答

从某种意义上说,结构化编程构造优先于(有些非结构化的)中断和继续语句,这是不好的。相比之下,根据这一原则,他们更喜欢“去”。

我总是建议让你的代码尽可能结构化……不过,正如乔恩·斯基特指出的那样,不要让它更有条理!

这更像是一个美观的东西,更容易阅读代码,你明确地知道为什么循环会在循环的声明中停止。

对我来说,问题在于可读性。

带有true条件的while语句不会告诉您任何关于循环的信息。这使得理解它的工作更加困难。

从这两个片段中更容易理解什么?

do {
  // Imagine a nice chunk of code here
} while(true);

do {
  // Imagine a nice chunk of code here
} while(price < priceAllowedForDiscount);

这是你的枪,你的子弹和你的脚…

说它不好是因为你在自找麻烦。你或本页上的任何其他海报都不会有简短的while循环的例子。

麻烦将在未来某个非常随机的时间开始。可能是其他程序员造成的。可能是安装软件的人。可能是最终用户。

为什么?我必须找出为什么700K的LOC应用程序会逐渐开始消耗100%的CPU时间,直到每个CPU都饱和。这是一个神奇的while (true)循环。这件事又大又恶心,但归结起来就是:

x = read_value_from_database()
while (true) 
 if (x == 1)
  ...
  break;
 else if (x ==2)
  ...
  break;
and lots more else if conditions
}

没有最后的其他分支。如果值不匹配If条件,循环将一直运行到时间结束。

当然,程序员指责最终用户没有选择程序员期望的值。(然后我在代码中删除了while(true)的所有实例。)

恕我直言,使用while(true)这样的结构并不是很好的防御性编程。它会回来困扰你的。

(但我确实记得,如果我们不评论每一行,教授就会扣分,即使是i++;)

如果您的循环在后台线程上运行,这可能会很糟糕,因此当您通过终止一个UI线程来关闭应用程序时,这段代码将继续执行。正如其他人已经说过的,你应该总是使用某种支票来提供一种取消的方式。