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

时间:2008-10-28 19:08:58

标签: refactoring loops while-loop

如果像我一样,你在一个While(True)循环的位置颤抖,那么你也必须经过长时间的努力思考重构它的最佳方法。我已经看到了几种不同的实现,没有比其他任何实现更好,例如计时器和放大器。代表组合。

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

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

12 个答案:

答案 0 :(得分:59)

我的偏好是

start:

   // code goes here

goto start;

这最清楚地表达了意图。祝你好运,超越你的编码标准。 (想知道这将花费多少业力)。

答案 1 :(得分:22)

有什么可怕之处呢?尝试找到一个常见的中断条件并将其重构为循环的头部。如果这不可能 - 很好。

答案 2 :(得分:22)

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

转到曾经是编码标准中的黑羊。我遇到了算法,其中 goto 使代码更具可读性和更短。有时不值得重构(或者更好地使用 goto )。

另一方面,您可以在大多数情况下避免而(true)

答案 3 :(得分:13)

当我遇到一个while(true)循环时,它告诉我

  1. 在循环的顶部(或底部)不容易测试断裂条件,
    • 有多个休息条件,
    • 或者之前的程序员太懒了,不能正确地考虑循环。
  2. 1和2意味着您可以坚持同时(true)。 (我使用for(;;),但在我看来这是一种风格的东西。)我有另一张海报,为什么害怕这个?我害怕有折磨的循环,跳过篮球,让循环“正确”滚动。

答案 4 :(得分:12)

将True替换为您将用于突破循环的条件。

如果是服务或后台线程,您可以使用:

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

答案 5 :(得分:11)

为什么要重构?关于这个结构有什么“可怕”?它被广泛使用,并且被很好地理解。

如果没有损坏,请不要修复它。

答案 6 :(得分:7)

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

当我们制造热泵控制器时,有一种电源自检(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。但我喜欢假装将来某个版本会有模式改变。

答案 7 :(得分:7)

#define ever 1
for (;ever;)

嗯,请保持原样,而(真实)可能会像你要的那样清晰......

答案 8 :(得分:3)

错误,是一个重构......

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

好吧,如果您的语言支持Tail调用....

答案 9 :(得分:3)

如果你想让它无限期地继续直到程序流完全流产,我看不到有什么问题(true)。我最近在一个.NET数据收集服务中遇到了它,它将(true)与thread.sleep结合起来,每分钟唤醒并轮询第三方数据服务以获取新报告。我考虑过用计时器和委托重构它,但最终决定这是最简单易读的方法。 10次​​中有9次清晰的代码味道,但是当没有退出状态时,为什么会让事情变得更加困难?

答案 10 :(得分:1)

当无限循环包含在窗口中并且随窗口死亡时,我不介意。

想想Hasselhoff递归。

答案 11 :(得分:-2)

void whiletrue_sim(void)
  {
    //some code
    whiletrue_sim();
  }

警告:您的堆栈可能会溢出,具体取决于语言,优化程序和其他内容。