当前位置:  开发笔记 > 编程语言 > 正文

是(真的)与破坏不良的编程实践?

如何解决《是(真的)与破坏不良的编程实践?》经验,为你挑选了6个好方法。

我经常使用这个代码模式:

while(true) {

    //do something

    if() {
        break;
    }

}   

另一位程序员告诉我,这是不好的做法,我应该用更标准的替换它:

while(!) {

    //do something

}   

他的理由是你可以"轻易地忘记休息"并拥有无限循环.我告诉他,在第二个例子中你可以很容易地放入一个永远不会返回真实的条件,因此很容易有一个无限循环,所以两者都是同样有效的做法.

此外,我经常更喜欢前者,因为当你有多个断点时,即当多个条件退出循环时,它使代码更容易阅读.

任何人都可以通过为一方或另一方添加证据来丰富这一论点吗?



1> Andrew G. Jo..:

两个例子之间存在差异.第一个将每次至少执行一次"做某事",即使该陈述永远不是真的.当语句评估为true时,第二个只会"做某事".

我认为你要找的是一个do-while循环.我100%同意这while (true)不是一个好主意,因为它使得维护这段代码变得困难,并且你正在逃避循环的方式非常goto糟糕,这被认为是不好的做法.

尝试:

do {
  //do something
} while (!something);

查看您的个人语言文档以获取确切的语法.但是看看这个代码,它基本上做了什么,然后检查while部分,看它是否应该再做一次.


这个答案没有考虑到更常见的习语:while(true){/*做某事*/if(条件)中断;/*做更多的事情*/}这避免重复"做某事"部分:/*做某事*/while(条件){/*做更多事情*//*做点什么*/}
我经常对服务中的工作线程使用while(true)...仅在线程中止异常的情况下返回...

2> joel.neely..:

引用那些着名的开发者的消息,华兹华斯:

......
事实上,监狱,我们
自己毁灭,没有监狱; 因此,对于我来说,
在各种各样的情绪中,"
在十四行诗的地面内,两个人的消遣将被束缚;
如果有些灵魂(因为他们的需要必须是这样),那些
已经感受到太多自由的重量的人会感到高兴,
应该在那里找到简短的慰借,正如我所发现的那样.

华兹华斯接受了十四行诗作为一个解放框架的严格要求,而不是作为一件紧身衣.我建议"结构化编程"的核心是放弃构建任意复杂的流程图的自由,以支持易于理解的解放.

我自由地同意,有时提前退出是表达行动的最简单方式.然而,我的经验是,当我强迫自己使用最简单的控制结构(并且真的考虑在这些约束内进行设计)时,我经常发现结果更简单,代码更清晰.缺点

while (true) {
    action0;
    if (test0) break;
    action1;
}

是很容易让action0action1越来越大的代码块,或加上"只是多了一个"测试突破的动作序列,直到它变得难以指向特定的线和回答这个问题,"条件做什么,我知道这一点吗?" 因此,在没有为其他程序员制定规则的情况下,我尽可能避免while (true) {...}在我自己的代码中使用成语.



3> Norman Ramse..:

当您可以在表单中编写代码时

while (condition) { ... }

要么

while (!condition) { ... }

没有出口(break,continue,或goto在体内),该形式是优选的,因为对方能读取的代码,并只通过观察头部理解终止条件.非常好.

但是很多循环不适合这个模型,中间有明确退出无限循环是一个光荣的模型.(循环continue通常比循环更难理解break.)如果你想要一些证据或权威来引用,那么Don Knuth关于Goto语句的结构化编程的着名论文就是最好的选择; 你会找到你想要的所有例子,论点和解释.

成语的一个小问题:将while (true) { ... }你作为一个旧的Pascal程序员写作品牌,或者现在可能是Java程序员.如果您使用C或C++编写,那么首选的习惯用语就是

for (;;) { ... }

这没有充分的理由,但你应该这样写,因为这是C程序员期望看到它的方式.


#define ever(;;)
为了以防万一,请为了上帝的爱,实际上不要定义任何这些宏......
我从来没有见过任何喜欢(;;;){}的C程序员而在(1){}
如果我没记错的话,K&R首选(;;){}而(1){}

4> Bill the Liz..:

我更喜欢

while(!) {
    //do something
}

但我认为这更多的是可读性问题,而不是"忘记休息"的可能性.我认为忘记这break是一个相当弱的论点,因为这将是一个错误,你会立即找到并修复它.

我反对使用a break来摆脱无限循环的论点是你基本上使用break语句作为goto.我并不虔诚地反对使用goto(如果语言支持它,这是公平的游戏),但如果有更可读的选择,我会尝试替换它.

在多break点的情况下,我会替换它们

while( ! ||
       ! ||
       ! ) {
    //do something
}

以这种方式整合所有停止条件使得更容易看到将结束此循环的内容. break陈述可以洒在周围,这是可读的.



5> Martin Becke..:

虽然(true)可能有意义,如果你有很多语句,你想要停止,如果有任何失败

 while (true) {
     if (!function1() ) return;   
     if (!function2() ) return;   
     if (!function3() ) return;   
     if (!function4() ) return;  
   }

比...更好

 while (!fail) {
     if (!fail) {
       fail = function1()
     }           
     if (!fail) {
       fail = function2()
     }  
     ........

   }


然后,四个if可以被重写并移动到while条件:while(function1()&& function2()...)

6> joel.neely..:

哈维尔对我之前的回答(引用华兹华斯的一篇文章)做了一个有趣的评论:

我认为while(true){}是一个比'while(condition){}更"纯粹"的构造.

我无法用300个字符作出充分回应(对不起!)

在我的教学和指导中,我非正式地将"复杂性"定义为"为了能够理解这一行或表达,我需要在其余的代码中使用多少代码?" 我必须记住的东西越多,代码就越复杂.代码告诉我的越多,就越不复杂.

因此,为了降低复杂性,让我回答Javier的完整性和力量,而不是纯度.

我想到了这段代码:

while (c1) {
    // p1
    a1;
    // p2
    ...
    // pz
    az;
}

同时表达两件事:

    只要c1保持真实,(整个)身体将重复,并且

    在点1,其中a1执行,c1保证持有.

差异是透视之一; 第一个问题与整个循环的外部动态行为有关,而第二个则有助于理解我a1特别考虑的内在静态保证.当然,净效应a1可能会失效c1,要求我更难以理解我在第2点可以依赖的东西等.

让我们用一个特定的(微小的)例子来考虑条件和第一个动作:

while (index < length(someString)) {
    // p1
    char c = someString.charAt(index++);
    // p2
    ...
}

"外部"问题是,循环显然正在做一些事情someString,只有在index定位的时候才能完成someString.这就建立了一种期望,我们将在身体内部indexsomeString在身体内部进行修改(在我检查身体之前不知道的位置和方式),以便最终终止.这给了我思考身体的背景和期望.

"内在"问题是我们保证第1点之后的操作是合法的,所以在第2点阅读代码时,我可以考虑用我知道合法获得的char值做什么.(如果someString是null ref,我们甚至无法评估条件,但我也假设我们已经在这个示例的上下文中保护了它!)

相比之下,形式的循环:

while (true) {
    // p1
    a1;
    // p2
    ...
}

让我了解这两个问题.在外层,我想知道这是否意味着我真的应该期望这个循环永远循环(例如操作系统的主事件调度循环),或者是否还有其他事情发生.这既没有给出阅读身体的明确背景,也没有给出对(不确定的)终止进展的预期.

在内在层面,我绝对没有明确保证可能在第1点出现的任何情况.这个条件true在任何地方都是正确的,是关于我们在程序中任何一点可以知道的最弱的陈述.在尝试考虑行动完成时,了解行动的先决条件是非常有价值的信息!

因此,我认为这个while (true) ...成语比while (c1) ...我上面描述的逻辑更加不完整和弱,因此更复杂.

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有