如何检查平等? (0 == i)或(i == 0)

好的,我们知道以下两行是相同的 –

  1. (0 == i)
  2. (i == 0)

另外,过去也鼓励第一种方法,因为如果不小心使用了'='而不是'==',编译器会给出错误信息。

我的问题是 – 在今天这一代非常漂亮的IDE和智能编译器中,你还推荐第一种方法吗?

特别是,当我看到下面的代码时,这个问题突然出现在我的脑海里:

 if(DialogResult.OK == MessageBox.Show("Message")) ... 

在我看来,我绝不会推荐以上。 任何第二个意见?

我更喜欢第二个,(i == 0),因为读它时感觉更自然。 你问人们:“你是21岁还是老年人?”,而不是“21岁小于或等于你的年龄?”

如果你把variables放在第一个或最后一个,那么在C#中并不重要,因为赋值不计算为bool(或者可转换为bool的东西),所以编译器会捕获任何错误,如“if(i = 0)EntireCompanyData.Delete )”

所以,至less在C#世界里,这是一个风格而不是绝望的问题。 而把variables放到最后对于说英语的人来说是不自然的。 因此,对于更多的可读代码,首先是variables。

如果你有一个不能被交换机很好地表示的ifs列表(因为语言限制,也许),那么我想看看:

 if (InterstingValue1 == foo) { } else if (InterstingValue2 == foo) { } else if (InterstingValue3 == foo) { } 

因为它可以让您快速查看哪些是您需要检查的重要值。

特别是在Java中,我发现它是有用的:

 if ("SomeValue".equals(someString)) { } 

因为someString可能为null,这样你永远不会得到一个NullPointerException。 如果你正在比较你知道永远不会为null的常量和可能为null的对象,这也是一样的。

  1. (0 == i)

我会一直挑这个。 确实,今天的大多数编译器都不允许在条件语句中指定一个variables,但事实是,有些是这样做的。 在今天的networking编程中,我必须在系统上使用无数的语言。 通过使用0 ==我,我总是知道条件语句是正确的,我不依赖于编译器/解释器来为我解决我的错误。 现在,如果我必须从C#跳转到C ++或JavaScript,我知道我不必在代码中追踪条件语句中的赋值错误。 对于这么小的东西,为了节省这么多时间,这是一个没有道理的东西。

你知道,我总是使用if(i == 0)格式的条件,我这样做的理由是我写的大部分代码在C#(它会标记另一个),我做一个testing第一方法来发展我的testing通常会发现这个错误。

我曾在商店里尝试过强制实现0 == i格式,但是我发现编写起来很尴尬,难以记忆,并且最终成为正在寻找低成本的代码审阅者的饲料。

我曾经相信,更可读的选项(我= 0)是更好的方式去。

然后,我们有一个生产缺陷(不是我的),其中问题是($ var = SOME_CONSTANT)types的错误。 客户开始收到其他客户的电子邮件。 敏感型数据也是如此。

你可以争辩说,Q / A应该已经抓住了,但他们没有,这是一个不同的故事。

从那天起我一直推(0 == i)版本。 它基本上消除了这个问题。 这感觉不自然,所以你要注意,所以你不要犯错误。 没有办法在这里弄错了。

这也很容易被发现,有人没有在代码审查中反转if语句,而不是在if中意外地赋值。 如果格式是编码标准的一部分,人们会寻找它。 人们通常不会在代码审查期间debugging代码,并且眼睛似乎扫描(i = 0)vs(i == 0)。

我也是java的“常量string”.equals(dynamicString)更大的粉丝,没有空指针exception是一件好事。

其实,DialogResult的例子是我会推荐这个风格的地方。 如果可以看到的话,它将if()的重要部分放在左边。 如果它在右边,并且MessageBox有更多的参数(这很可能),那么您可能需要向右滚动才能看到它。

OTOH,我从来没有在“(0 == i)”风格看到太多的用处。 如果你可以记得先把常数放在一起,你可以记住使用两个等号,

我总是使用第一种情况(0 == i),这使我的生活保存了几次!

我认为这只是一个风格问题。 这确实有助于意外地使用赋值运算符。

我绝对不会让程序员长大。

我更喜欢(我= 0),但我仍然为自己做一个“规则”(0 ==我),然后每次打破它。

“呃?”,你想。

那么,如果我正在做一个左值的明智决定,那么我就注意到我打字的时候注意的是如果我为“==”input“=”。 我希望。 在C / C ++中,我通常使用-Wall作为自己的代码,无论如何,它都会在gcc上产生大部分的“=”错误。 我不记得最近看到这个警告,也许是因为我越来越反思偏执狂,我是关于我以前犯的错误。

 if(DialogResult.OK == MessageBox.Show("Message")) 

似乎误导了我。 诀窍的要点是避免意外分配给某些东西。

但是,谁来说DialogResult.OK是否比MessageBox.Show(“Message”)更可能或更不可能评估为可分配types呢? 在Java中,方法调用不可能是可分配的,而字段可能不是最终的。 所以如果你担心键入= ==,那么这个例子其实应该是Java的另一种方式。 在C ++中,两者都不可分配。

(0 == i)只是有用的,因为你绝对肯定知道数字文字是永远不可分配的,而我可能是。

当比较的两边都是可分配的时候,你不能以这种方式保护你自己免受意外的分配,而当你不知道哪一个是可分配的,而不是查找它的时候。 没有魔术说“如果你把他们反直觉的方式,你会安全的”。 虽然我认为这个问题引起了人们的关注,就像我的“总是违反规则”一样。

我使用(i == 0)的原因是它读得更好。 它使我脑海中stream畅的stream动。 当你为了debugging或者其他目的而把代码读回给自己的时候,它就像阅读一本书一样stream动,而且更有意义。

我的公司刚刚放弃了从编码标准中(0 == i)的要求。 我可以看出这是多么的合理,但在实践中似乎倒退了。 有点遗憾,默认情况下,C编译器可能不会给你一个关于if(i = 0)的警告。

第三个选项 – 完全禁止在条件内分配:

在高可靠性的情况下,不允许你在条件语句中分配一个variables(在前面的注释中没有很好的解释) – 它完全消除了这个问题,因为你可以在编译器或LINT中closures它,只有在非常受控制的情况下你可以使用它吗?

请记住,无论分配发生在条件还是外部,通常都会生成相同的代码 – 这只是减less代码行数的快捷方式。 这个规则总是有例外的,但是它永远不必在有条件的情况下 – 如果需要的话,你总是可以写出自己的出路。

所以另外一个select就是不允许这样的语句,并且在需要的地方使用注释来closures对这个常见错误的LINT检查。

-亚当

我会说,如果你试图用简单(和模棱两可的)的英语来expression一句话,那么(i == 0)听起来会更自然。 这实际上取决于程序员的编码风格或者他们需要遵守的标准。

就我个人而言,我不喜欢(1),总是做(2),但是在处理对话框和其他方法时,为了可读性,这种方法会变得更加可读。 它看起来并不坏,但是如果将MessageBox展开为全长。 你必须一直滚动,找出你正在返回什么样的结果。

所以虽然我同意你对价值types的简单比较的断言,但我不一定认为它应该是诸如消息框之类的东西的规则。

两者是平等的,但我宁愿略微0 ==我变种。

当比较string时,比较“MyString”.equals(getDynamicString())更容易出错

因为,getDynamicString()可能返回null。 要更加conststent,写0 ==我

那么,这取决于有问题的语言和编译器。 上下文就是一切。

在Java和C#中,除了比较两个布尔值的非常罕见的情况之外,“赋值而不是比较”input错误以无效的代码结束。

我可以理解为什么人们可能想要在C / C ++中使用“安全”forms – 但坦率地说,如果你犯了错字,大多数C / C ++编译器会警告你。 如果你使用的编译器没有,你应该问自己为什么:)

第二种forms(variables然后是常数)在我的视图中更具可读性 – 所以在任何地方都不会造成问题,我使用它。

所有编码标准的规则0应该是“编写可被另一个人轻松读取的代码”。 因此,在这种情况下,我会select(最迅速变化的值)testing(更快的变化值或常量),即“i == 0”。

即使这种方法有用,规则应该是“避免在比较的左边放一个左值”,而不是“总是在左边放任何常数”,这就是它通常被解释的方式 – 例如,没有任何东西从写作中获得

 if (DateClass.SATURDAY == dateObject.getDayOfWeek()) 

如果getDayOfWeek()返回一个常量(因此不是一个左值)!

我很幸运(在这方面,至less),在这些日子里,我主要是用Java编码,如前所述,如果(someInt = 0)将不能编译。

关于比较两个布尔值的警告是一个红鲱鱼,因为大多数时候你要比较两个布尔variables(在这种情况下交换他们轮不起作用)或testing是否设置了一个标志, -betide-you,如果我发现你比较你的条件中的任何明确的 ! GRRRR!

在C中,是的,但是你应该已经打开了所有的警告,并且正在编译警告,许多C编译器将帮助你避免这个问题。

我很less从可读性POV中看到很多好处。

代码可读性对于大于几百行的代码来说是最重要的事情之一,并且绝对地,i == 0读取比反向代码更容易

也许不是你的问题的答案。 我尝试使用===(检查相同),而不是相等。 这种方式没有types转换完成,它迫使程序员确保正确的types被传递,

你是对的,首先把重要的组件放置在可读性上,因为读者倾向于主要浏览左栏,并且在那里放置重要的信息有助于确保它被注意到。

但是,不要向同事讲话,暗示这是你的行为,即使是开玩笑也不会在这里得到高分。

我总是用第二种方法去。 在C#中,写作

 if (i = 0) { } 

导致编译器错误(无法将int转换为布尔值),以至于出现错误并不是问题。 如果你testing一个布尔,编译器仍然发出一个警告,你不应该比较布尔真或假。 现在你知道为什么了。

我个人更喜欢使用variables操作数值格式,部分原因是我一直在使用variables操作数值格式,以至于感觉“自然”,部分原因似乎是占主导地位的惯例。 有一些语言使用如下的赋值语句:

 :1 -> x 

所以,在这些语言的语境下,即使它是有效的,也可以看到以下内容:

 :if(1=x) 

所以这也是需要考虑的事情。 我同意消息框响应是一种情况,使用值操作数variables格式从可读性的angular度来看效果更好,但是如果您正在寻找常量,那么您应该放弃它的使用。

这是我最大的宠物之一。 没有理由减less代码的可读性(如果(0 == i),什么?0的值如何改变?)来捕捉任何在过去二十年中编写的C编译器可以自动捕获的东西。

是的,我知道,大多数C和C ++编译器默认情况下不会打开此项。 查找适当的开关打开它。 没有理由不知道你的工具。

当我看到它正在蔓延到其他语言(C#,Python),它通常会标记它,真的让我紧张!

我相信唯一的因素就是如果工具链没有提供警告来捕捉expression式中的赋值, 作为开发者,我的偏好是无关紧要的。 清楚地expression业务逻辑可以更好地expression。 如果(0 == i)比(i == 0)更合适,我会select它。 如果不是,我会select其他。

expression式中的许多常量由符号名称表示。 一些风格指南也限制了可用于标识符的语音部分。 我使用这些作为指导来帮助塑造expression式的读法。 如果结果expression式像伪代码一样松散地读取,那么我通常会满意的。 我只是让expression自己,如果我错了,通常会被同行评审。

我们可能会继续讨论我们的IDE有多好,但是我们仍然对那些将IDE转化为警告级别的人感到震惊。

因此,对于我来说,最好让人们使用(0 == i),因为你永远不知道哪个程序员在做什么。 “安全而不是抱歉”

 if(DialogResult.OK == MessageBox.Show("Message")) ... 

总是build议这样写比较。 如果MessageBox.Show(“Message”)的结果可能为空,那么如果比较是相反的话,那么就冒着NPE / NRE的风险。

math和逻辑运算在包含NULL的世界中不是自反的。