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


当前回答

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

其他回答

早在1967年,Edgar Dijkstra在一份行业杂志上写了一篇文章,讲述了为什么应该从高级语言中删除goto以提高代码质量。一种叫做“结构化编程”的编程范式由此而来,尽管当然不是每个人都同意goto自动意味着糟糕的代码。

结构化编程的关键本质上是代码的结构应该决定它的流,而不是在任何可能的情况下使用goto或break或continue来决定流。类似地,在该范例中也不鼓励有多个循环或函数的入口和出口点。

显然,这不是唯一的编程范式,但通常它可以很容易地应用到其他范式,如面向对象编程(比如Java)。

你的老师可能已经被教导过,并且正试图教导你的班级,我们最好通过确保我们的代码是结构化的,并遵循结构化编程的隐含规则来避免“意大利面条代码”。

While there is nothing inherently "wrong" with an implementation that uses break, some consider it significantly easier to read code where the condition for the loop is explicitly specified within the while() condition, and eliminates some possibilities of being overly tricky. There are definitely pitfalls to using a while(true) condition that seem to pop up frequently in code by novice programmers, such as the risk of accidentally creating an infinite loop, or making code that is hard to read or unnecessarily confusing.

具有讽刺意味的是,异常处理是一个与结构化编程有偏差的领域,并且随着您对Java编程的深入了解,这种偏差肯定会出现。

也有可能你的老师希望你展示你使用特定循环结构或语法的能力,而你写的代码在功能上是等价的,你可能没有展示你应该在那一课中学习的特定技能。

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

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

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

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

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

我猜用break对老师来说就像折断树枝来得到果实,用一些其他的技巧(向树枝鞠躬),这样你得到了果实,而树枝仍然活着。

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

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

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

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