可怕的 While (True) 循环的最佳重构

问题描述 投票:0回答:12

如果您像我一样,在 While (True) 循环处颤抖,那么您也一定已经认真思考了重构它的最佳方法。 我见过几种不同的实现,没有一个比其他实现更好,例如计时器和委托组合。

那么您想出或看到的重构可怕的 While (True) 循环的最佳方法是什么?

编辑:正如一些评论提到的,我的目的是让这个问题成为一个“无限循环”重构,例如运行 Windows 风格的服务,其中唯一的停止条件是 OnStop 或致命异常。

refactoring loops while-loop
12个回答
68
投票

我的偏好是

start:

   // code goes here

goto start;

这最清楚地表达了意图。 祝你好运,让它通过你的编码标准。 (不知道这会让我付出多少业力)。


28
投票

我们真的需要重构 while(true) 循环吗? 有时它是一种编码标准,大多数开发人员已经习惯了这种结构。如果你必须认真思考如何重构这段代码,你确定重构它是个好主意吗?

Goto曾经是编码标准中的害群之马。我遇到过一些算法,其中 goto 使代码更具可读性和更短。有时并不值得重构(或者最好使用 goto)。

另一方面,大多数时候你可以避免 while(true)


23
投票

有什么好害怕的?尝试找到一个常见的中断条件并将其重构为循环的头部。如果那不可能——那好吧。


18
投票

当我遇到 while(true) 循环时,这会告诉我

  1. 在循环的顶部(或底部)不容易测试中断条件,
  2. 有多种中断条件,
  3. 或者之前的程序员太懒了,无法正确分解循环。

1 和 2 意味着你最好还是坚持使用 while(true)。 (我使用

for(;;)
,但在我看来这是一种风格。)我和另一张海报在一起,为什么害怕这个? 我害怕那些扭曲的循环,它会跳过铁环,让循环“正确地”滚动。


14
投票

为什么要重构? 这个构造有何“可怕”之处? 它被广泛使用,并且很好理解。

如果它没有坏,就不要修理它。


14
投票

将 True 替换为您要用来跳出循环的条件。

对于服务或后台线程,您可以使用:

volatile bool m_shutdown = false;
void Run()
{
    while (!m_shutdown)
    { ... }
}

8
投票

“永远运行”的情况有时是更大状态机的一部分。 许多嵌入式设备(具有永远运行循环)并不真正运行永远。 它们通常有多种操作模式,并会在这些模式之间排序。

当我们构建热泵控制器时,有一个运行一段时间的开机自检(POST)模式。 然后是一个初步的环境收集模式,直到我们弄清楚所有区域和恒温器以及其他什么。

一些工程师声称接下来发生的是“永远运行”循环。 事情其实没那么简单。 实际上是几种运营模式的反复变换。 有加热、除霜、冷却、怠速和其他东西。

我的偏好是将“永远”循环视为实际上只是一种操作模式 - 将来的某个时候可能还会有其他模式。

someMode= True
while someMode:
    try:
        ... do stuff ...
    except SomeException, e:
        log.exception( e )
        # will keep running
    except OtherException, e:
        log.info( "stopping now" )
        someMode= False

在某些情况下,到目前为止我们还没有看到将

someMode
设置为
False
。 但我喜欢假装在未来的版本中会有模式更改。


8
投票
#define ever 1
for (;ever;)

嗯,就让它保持原样,而 (true) 可能与你所得到的一样清晰..


5
投票

errr,要重构......

  • 用无限递归替换无限循环:-)

好吧,如果你有一种支持 Tail 调用的语言......


4
投票

如果你希望它无限期地继续下去,直到程序流完全中止,我认为 while (true) 没有任何问题。 我最近在 .NET 数据收集服务中遇到了这种情况,该服务将 while (true) 与 thread.sleep 结合起来,每分钟唤醒一次并轮询第三方数据服务以获取新报告。 我考虑用计时器和委托来重构它,但最终认为这是最简单、最容易阅读的方法。 十分之九的情况是明显的代码味道,但是当没有退出条件时,为什么要让事情变得更加困难呢?


2
投票

当无限循环包含在窗口内并随窗口一起终止时,我不介意。

想想哈塞尔霍夫递归。


-2
投票
void whiletrue_sim(void)
  {
    //some code
    whiletrue_sim();
  }

警告:您的堆栈可能会溢出。

© www.soinside.com 2019 - 2024. All rights reserved.