it-swarm.cn

难道“如果(0 ==值)...”弊大于利?

当我在别人的代码中看到它时,这是我最讨厌的事情之一。我知道它的含义,以及为什么有人这样做(“如果我不小心放入'='会怎样?”)。对我来说,这就像一个孩子下楼时大声地数步。

无论如何,这是我反对的论点:

  • 它破坏了读取程序代码的自然流程。我们人类说“如果值等于零”而不是“如果值等于零”。
  • 当您的条件中有一个分配,或者实际上您的条件仅由该赋值组成时,现代编译器会警告您,是的,无论如何看起来都是可疑的
  • 如果您是程序员,则在比较值时不要忘了加双'='。您可能会忘记加上“!”。测试不平等时。
50
mojuba

嗯,是的,“ Yoda有条件”(“如果值为零,则必须执行此代码!”)。我总是指出任何声称自己“更好”使用lint(1)之类的工具的人。自70年代末以来,这个特殊的问题已经解决。大多数现代语言甚至都不会编译if(x = 10)之类的表达式,因为它们拒绝强制将赋值结果赋给布尔值。

正如其他人所说,这当然不是问题,但确实会引起一些认知失调。

59
TMN

它令人讨厌,因为它征收了少量但引人注目的精神税。

人们几乎以所有编程语言(和大多数自然语言)从左到右阅读。

如果我看到_123 == x_,我在心理上的解析方式是:

  • _123_-那又如何呢?信息不完整。
  • _==_-好吧,123是123,为什么要测试...
  • x-好的,这就是我们所关心的。直到现在我才有了上下文。
  • 返回重新考虑_123_以及为什么将x与之比较。

当我看到_x == 123_的心理分析是:

  • x-提供上下文,我知道条件是什么。我可能会选择忽略其余部分。根据先前的流程,我很好地知道了为什么以及接下来要发生什么(如果有所不同,我会感到惊讶)。
  • _==_-我是这样认为的。
  • _123_-是的。

中断很小(在一个简单示例中),但是我总是注意到了。

如果您要want引起注意,例如将if (LAUNCH_NUKES == cmd)。通常这不是故意的。

56
dbkk

有害?不行。

不良做法?值得商bat的。这是简单的防御性编程。

值得失去睡眠吗?没事.

47
Wonko the Sane

这基本上是flaimbait。

不,这样做弊大于利。简单。

还有更多字?

编译器参数? Erm,ish,也许-不要对编译器抱有太大的信心,以免您陷入困境。

“你不应该忘记”(duh-当然,你当然不应该在我累的同时,我整天都在编码,不得不使用两种不同的语言,有时,有时候,作为人,我会犯一个错误。

这种行为的关键在于它的防御性,它不存在,因为您期望犯错的可能性超过了购买保险所犯的错误,因为您期望崩溃的可能性……但是如果您做到这一点,那就可以了。

难以阅读?您抱怨的是,一个体面的程序员应该使用==进行硬接线(这会做出各种错误的假设),但是同一位体面的程序员无法读取0 == value?

不伤害,有潜在的好处,愚蠢的问题,如果其他人愿意,请继续这样做。

17
Murph

我不会称其为伤害,但令人讨厌。所以不,我不会说。

11
whatsisname

我从来没有感觉到整个“如果我忘记=会怎样?”。曾经真正担负过重。是的,您可能会打错字,但我们所有人都会打错字,更改整个编码样式似乎很愚蠢,因为您担心会犯错误。为什么不将所有变量和函数全部小写而不加标点符号,因为您可能会忘记大写某些东西或忘记下划线呢?

10
GSto

某些人使用它来明确弄清条件在做什么。例如:

方法1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

方式2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

有人认为第二个示例更为简洁,或者倒置参数说明了测试本身之前的测试要点(有条件的)。

实际上,我都不介意任何一种方式。我对风格充满热情,最大的矛盾是不一致。因此,请以相同的方式进行操作,始终如一,我也不会介意阅读您的代码。

混合起来,看起来好像六个不同的人立即用自己的独特风格进行处理,我有点生气。

9
Tim Post

对我来说,这很简单。作为(在20世纪90年代)学习过C和C++的人,我已经习惯了它并且仍然使用它,即使有很多原因也要学习。

一旦您“适应”了左侧的“常数”,它便成为第二天性。

我也仅将其用于等价(或取反的等价),而不用于大于/小于。

我完全同意@Wonko的回答。

6
DevSolo

我发现这很有用的一种情况是if的可变部分很长,并且看到这些值使代码更易于阅读。虚线命名空间语言就是最好的例子。

例如,我从事单点登录工作的情况是,如果发生某种类型的错误并以某种方式恢复,则可能会有两个并发会话,因此我必须为其添加一个处理程序,该处理程序在if外观内像这样的东西:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

诚然,在此示例中,还有其他方法可以执行此操作,但是在这种情况下,数字优先版本可能更具可读性。

5
Bill

但是错误仍然发生。有时您希望在循环运算符中进行赋值,否则可能会检查相等性,或者至少使用它是标准做法。

我对此有所保留。我所遵循的建议(可能来自Code Complete)是在比较中将左侧的较低值保持为原值。我之前与同事讨论过这个问题,他认为这有点疯狂,但我已经习惯了。

所以我会说:

if ( 0 <= value )

但是我也会说:

if ( value <= 100 )

平等我倾向于检查左边的变量,因为它更具可读性。

3
glenatron