“while(true)”循环有那么糟糕吗?[已关闭]

2022-08-31 05:52:42

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

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

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

我完全理解Java表亲的陷阱,并且我有不使用它们的明智之情。我也意识到,一个更完整的程序会提供一些其他的逃避方式,比如说结束程序,但这不是我的教授引用的原因,所以......gotobreak:label

有什么问题?do-while(true)


答案 1

我不会说这很糟糕 - 但同样,我通常至少会寻找替代方案。

在我写第一件事的情况下,我几乎总是至少尝试将其重构为更清晰的东西。有时它无法得到帮助(或者替代方案是有一个变量,除了指示循环的结束之外没有任何意义,不如语句清晰),但它至少值得尝试。boolbreak

作为比标志更清楚地使用的示例,请考虑:break

while (true)
{
    doStuffNeededAtStartOfLoop();
    int input = getSomeInput();
    if (testCondition(input))
    {
        break;
    }
    actOnInput(input);
}

现在让我们强制它使用标志:

boolean running = true;
while (running)
{
    doStuffNeededAtStartOfLoop();
    int input = getSomeInput();
    if (testCondition(input))
    {
        running = false;
    }
    else
    {
        actOnInput(input);
    }
}

我认为后者读起来更复杂:它有一个额外的块,缩进得更多,如果你试图弄清楚返回时会发生什么,你需要仔细查看块的其余部分,以检查块后面没有任何东西会发生,无论是否设置为。elseactOnInputtestConditiontrueelserunningfalse

该语句更清楚地传达了意图,并让块的其余部分继续执行它需要执行的操作,而不必担心早期条件。break

请注意,这与人们对方法中的多个 return 语句的论点完全相同。例如,如果我可以在前几行中计算出方法的结果(例如,因为某些输入为空,空或零),我发现直接返回该答案比使用变量来存储结果,然后是一整组其他代码,最后是一个语句更清晰。return


答案 2

AFAIK没什么,真的。老师只是过敏,因为他们在某个地方听说它真的很糟糕。否则你只会写:goto

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

这几乎是一回事。

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

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

}

推荐