前提
无论语言或所需功能如何,都应将以下代码视为错误格式:
while( true ) {
}
支持论点
循环的while( true )
形式很差,因为它:
- 打破 while 循环的隐含契约。
- 意味着它永远循环。
- 必须阅读循环内的代码才能理解终止子句。
- 永远重复的循环会阻止用户从程序中终止程序。
- 是低效的。
- 容易出现错误。
- 无法轻松确定将始终为每次迭代执行的代码放置在何处。
- 导致不必要的复杂代码。
- 自动源代码分析。
- 为了查找错误、程序复杂性分析、安全检查或在不执行代码的情况下自动导出任何其他源代码行为,指定初始中断条件允许算法确定有用的不变量,从而改进自动源代码分析指标。
- 无限循环。
- 如果每个人都总是使用
while(true)
不是无限的 for 循环,那么当循环实际上没有终止条件时,我们就失去了简洁交流的能力。(可以说,这已经发生了,所以这一点没有实际意义。)
“转到”的替代方案
以下代码是更好的形式:
while( isValidState() ) {
execute();
}
bool isValidState() {
return msg->state != DONE;
}
好处
没有旗帜。没有goto
。没有例外。容易改变。易于阅读。易于修复。另外代码:
- 将循环工作负载的知识与循环本身隔离开来。
- 允许维护代码的人轻松扩展功能。
- 允许在一处指定多个终止条件。
- 将终止子句与要执行的代码分开。
- 对核电站更安全。;-)
第二点很重要。在不知道代码如何工作的情况下,如果有人让我让主循环让其他线程(或进程)有一些 CPU 时间,我会想到两个解决方案:
选项1
轻松插入暂停:
while( isValidState() ) {
execute();
sleep();
}
选项 #2
覆盖执行:
void execute() {
super->execute();
sleep();
}
此代码比嵌入的循环更简单(因此更易于阅读)switch
。该isValidState
方法应该只确定循环是否应该继续。方法的主力应该被抽象到execute
方法中,它允许子类覆盖默认行为(使用嵌入式switch
and是一项艰巨的任务goto
)。
Python 示例
对比 StackOverflow 上发布的以下答案(针对 Python 问题):
- 永远循环。
- 要求用户输入他们的选择。
- 如果用户的输入是'restart',则永远继续循环。
- 否则,永远停止循环。
- 结尾。
代码
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
相对:
- 初始化用户的选择。
- 循环,而用户的选择是“重启”这个词。
- 要求用户输入他们的选择。
- 结尾。
代码
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
在这里,while True
会导致误导和过于复杂的代码。