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


当前回答

我想说,一般来说,它不被认为是一个好主意的原因是你没有充分发挥这个结构的潜力。此外,我倾向于认为许多编程教师不喜欢他们的学生带着“包袱”进来。我的意思是,我认为他们喜欢成为学生编程风格的主要影响因素。也许这只是老师的一个讨厌的地方。

其他回答

我想说,一般来说,它不被认为是一个好主意的原因是你没有充分发挥这个结构的潜力。此外,我倾向于认为许多编程教师不喜欢他们的学生带着“包袱”进来。我的意思是,我认为他们喜欢成为学生编程风格的主要影响因素。也许这只是老师的一个讨厌的地方。

Douglas Crockford说过,他多么希望JavaScript包含一个循环结构:

loop
{
  ...code...
}

我也不认为Java会因为拥有循环结构而变得更糟糕。

while(true)循环本身并没有什么错,但是老师们倾向于不鼓励它们。从教学的角度来看,很容易让学生创造出无穷无尽的循环,而不理解为什么循环没有被转义。

但是他们很少提到的是,所有的循环机制都可以用while(true)循环复制。

while( a() )
{
  fn();
}

loop
{
  if ( !a() ) break;
  fn();
}

and

do
{
  fn();
} while( a() );

等于:

loop
{
  fn();
  if ( !a() ) break;
}

and

for ( a(); b(); c() )
{
  fn();
}

等于:

a();
loop
{
  if ( !b() ) break;
  fn();
  c();
}

只要你能以一种工作的方式设置你的循环,你选择使用的结构是不重要的。如果它恰好适合for循环,则使用for循环。

最后一点:保持循环的简单性。如果在每次迭代中都需要执行许多功能,那么就将其放入一个函数中。在你让它工作之后,你总是可以优化它。

在我的很多函数中,我使用了类似的东西,但逻辑相反。

DWORD dwError = ERROR_SUCCESS;

do
{
    if ( (dwError = SomeFunction()) != ERROR_SUCCESS )
    {
         /* handle error */
         continue;
    }

    if ( (dwError = SomeOtherFunction()) != ERROR_SUCCESS )
    {
         /* handle error */
         continue;
    }
}
while ( 0 );

if ( dwError != ERROR_SUCCESS )
{
    /* resource cleanup */
}

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

2)你的老师错了。

NSFS ! !:

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

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