我已经用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(正确)怎么了?


当前回答

您可以使用一个布尔标志来指示何时结束while循环。中断和转向是软件难以维护的原因——软件危机(tm)——应该避免,也可以很容易地避免。

这是一个你是否务实的问题。实用的程序员在这种简单的情况下可能只使用break。

但是最好养成不使用它们的习惯,否则可能会在不合适的情况下使用它们,比如在复杂的嵌套循环中,代码的可读性和可维护性因使用break而变得更加困难。

其他回答

这并不是一件可怕的事情,但是在编码时您需要考虑其他开发人员。甚至在学校。

其他开发人员应该能够在循环声明中看到循环的退出子句。你没有那样做。您将退出子句隐藏在循环的中间,为其他试图理解您的代码的人增加了更多的工作。这也是避免使用“break”这类词汇的原因。

话虽如此,在现实世界中,您仍然会在大量代码中看到类似的东西。

也许是我运气不好。或许我只是缺乏经验。但是每次我回忆起处理while(true)内部有break时,可以改进将Extract Method应用到while-block的代码,它保留了while(true),但(巧合吗?)将所有的break转换为返回。

根据我的经验,没有休息(即返回或抛出)是相当舒服和容易理解的。


  void handleInput() {
      while (true) {
          final Input input = getSomeInput();
          if (input == null) {
              throw new BadInputException("can't handle null input");
          }
          if (input.isPoisonPill()) {
              return;
          }
          doSomething(input);
      }
  }

我认为这确实很糟糕……或者至少对许多开发人员来说是这样。这是开发人员不考虑循环条件的症状。因此很容易出错。

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

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

1) do -while没有错(正确)

2)你的老师错了。

NSFS ! !:

3)大多数老师是老师而不是程序员。