如何检查是否相等? (0 == i)或者(i == 0)
好的,我们知道以下两行是等效的-
(0 ==我)
(i == 0)
另外,过去鼓励使用第一种方法,因为如果我们不小心使用了" ="而不是" ==",那将允许编译器给出错误消息。
我的问题是在当今漂亮的IDE和智能编译器中,我们仍然推荐第一种方法吗?
特别是,当我看到以下代码时,这个问题突然浮现在脑海中-
if(DialogResult.OK == MessageBox.Show("Message")) ...
我认为,我永远不会推荐上述内容。还有其他意见吗?
解决方案
我认为这只是风格问题。它确实有助于意外使用赋值运算符。
我绝对不会要求程序员长大。
我更喜欢第二个(i == 0),因为在阅读时感觉自然得多。我们问别人:"我们年满21岁吗?"而不是" 21岁以下吗?"
我想说的是,(i == 0)如果我们尝试用普通(且模棱两可)的英语措辞,那听起来会更自然。实际上,这实际上取决于程序员的编码风格或者要求他们遵循的标准。
也许不是我们问题的答案。
我尝试使用===(检查是否相同)而不是相等性。这样就不会进行类型转换,并且会迫使程序员确保传递正确的类型,
我个人不喜欢(1)并总是喜欢(2),但是在处理对话框和其他可能很长的方法时,可读性却相反。看起来不错,但是如果我们将MessageBox扩展到全长,它看起来并不坏。我们必须一直滚动到最右边才能弄清楚返回的结果是什么。
因此,虽然我同意我们关于对值类型进行简单比较的主张,但我不一定认为这应该是消息框之类的规则。
我们认为正确的是,将重要的组件放在第一位有助于提高可读性,因为读者通常会首先浏览左栏,而将重要的信息放在此处有助于确保其被注意。
但是,切勿与同事交谈,这意味着即使我们开玩笑也将是举动,但在这里并不能给我们很高的评价。
如果我们有一个ifs列表不能用开关很好地表示(可能是由于语言限制),那么我宁愿看到:
if (InterstingValue1 == foo) { } else if (InterstingValue2 == foo) { } else if (InterstingValue3 == foo) { }
因为它使我们可以快速查看哪些是需要检查的重要值。
特别是在Java中,我发现这样做很有用:
if ("SomeValue".equals(someString)) { }
因为someString可能为null,所以我们将永远不会收到NullPointerException。如果我们将知道永远不会为null的常量与可能为null的对象进行比较,则同样适用。
我公司刚刚从其编码标准中删除了如果(0 == i)的要求。我可以看到它的意义,但实际上,它似乎是倒退的。遗憾的是,默认情况下,C编译器可能不会向我们发出有关if(i = 0)的警告。
在Cif中,将变量放在第一个还是最后一个都没关系,因为赋值的结果不是布尔值(或者可转换为布尔值的变量),因此编译器会捕获任何错误,例如" if(i = 0)EntireCompanyData.Delete() "
因此,至少在Cworld中,这是样式问题,而不是绝望问题。将变量置于最后对于英语使用者来说是不自然的。因此,对于更具可读性的代码,请先可变。
实际上,DialogResult示例是我将推荐该样式的地方。如果可以看到,它将if()的重要部分向左放置。如果它在右侧并且MessageBox具有更多参数(可能),则可能必须向右滚动才能看到它。
太太了,我从没见过用((0 == i))样式有太多用处。如果我们记得将常数放在第一位,则可以记得使用两个等号,
我总是选择第二种方法。用C#编写
if (i = 0) { }
无论如何都会导致编译器错误(无法将int转换为bool),因此我们可能犯的错误实际上不是问题。如果我们测试布尔值,则编译器仍会发出警告,并且我们不应该将布尔值与true或者false进行比较。现在你知道为什么了。
两者是相等的,尽管我更喜欢0 == i变体。
比较字符串时,比较" MyString" .equals(getDynamicString())更容易出错。
由于getDynamicString()可能返回null。
为了更稳定,写0 == i
好吧,这取决于所使用的语言和编译器。上下文就是一切。
在Java和C#中,除了比较两个布尔值的极少数情况外,"赋值而不是比较"的错字最终以无效的代码结尾。
我能理解为什么人们可能想在C / C ++中使用"安全"格式,但是坦率地说,如果我们仍然输入错误,大多数C / C ++编译器都会警告我们。如果我们使用的编译器不支持,则应该问自己为什么:)
在我看来,第二种形式(先是可变然后是常数)更具可读性,因此我绝对会在绝对不会造成问题的任何地方使用它。
我更喜欢(i == 0),但我还是为自己做一个"规则"(0 == i),然后每次都将其破坏。
"嗯?",你想。
好吧,如果我正在做出一个明智的决定,将一个左值放在左侧,那么我会充分注意要输入的内容,以注意是否为" =="输入了" ="。我希望。在C / C ++中,我通常对自己的代码使用-Wall,无论如何,它都会在gcc上为大多数==的错误生成一个警告。我不记得最近看到过这样的警告,也许是因为我编程的时间越长,我对自己以前犯的错误就越反省。
if(DialogResult.OK == MessageBox.Show("Message"))
对我来说似乎是误入歧途。诀窍的关键是避免意外分配给某些东西。
但是,谁说DialogResult.OK与MessageBox.Show(" Message")相比,求值给可分配类型的可能性更大还是更低?在Java中,方法调用不可能是可分配的,而字段可能不是最终的。因此,如果我们担心为==键入=,那么对于此示例,在Java中实际上应该是相反的方式。在C ++中,两者都不是可分配的。
(0 == i)仅有用,因为我们可以绝对确定数字文字永远都不能赋值,而我只是可以赋值。
当比较的双方都可以分配时,我们就无法通过这种方式保护自己免受意外分配的影响,这就是当我们不查找而又不知道哪个可以分配时。没有魔术说"如果我们以相反的方式摆放它们,那将是安全的"。尽管我认为它引起了人们对这一问题的关注,但其方式与我的"始终违反规则"规则相同。
我们知道,我始终使用条件的if(i == 0)格式,而这样做的原因是,我用C编写了大部分代码(无论如何都会标记另一个),并且我先进行测试无论如何,我的开发和测试方法通常都会捕获此错误。
我曾在一些商店中尝试执行0 == i格式,但是我发现编写该代码很尴尬,想起它很尴尬,最终对于那些正在寻找低垂的水果的代码审阅者来说,这是一个麻烦。
我正在尝试始终使用第一种情况(0 == i),这挽救了我的生命几次!
我们可能会继续谈论我们的IDE的发展情况,但是仍然有很多人拒绝将IDE的警告级别降低,这让我感到震惊。
因此,对我而言,最好让人们使用(0 == i),这是我们永远不知道的,哪个程序员在做什么。
最好要"安全胜过后悔"
我个人更喜欢使用变量-操作数-值格式,部分原因是我一直在使用它,以至于感觉到"自然",部分原因是因为它似乎占主导地位。有一些使用赋值语句的语言,例如:
:1 -> x
因此,在这些语言的上下文中,即使它是有效的,看到以下内容也会变得很混乱:
:if(1=x)
因此,这也是要考虑的问题。我确实同意消息框响应,这是从可读性的角度来看,使用值操作数可变格式更好的一种情况,但是,如果我们正在寻找恒定性,那么就应该放弃它的使用。
- (0 ==我)
我将永远选择这个。的确,当今大多数编译器都不允许在条件语句中分配变量,但事实是有些这样做。在当今的网络编程中,我必须在系统上使用多种语言。通过使用0 == i,我总是知道条件语句将是正确的,并且我不依赖于编译器/解释器来为我捕获错误。现在,如果我必须退出Cto C ++或者JavaScript,我知道我将不必在代码的条件语句中追踪赋值错误。对于这么小的东西,并节省它的时间,这是没有道理的。
这是我最大的宠儿之一。没有理由降低代码的可读性(如果(0 == i),那是什么?0的值如何变化?)以捕获过去二十年来编写的任何C编译器都可以自动捕获的内容。
是的,我知道,大多数C和C ++编译器默认情况下都不会启用此功能。查找适当的开关以将其打开。不知道工具是没有任何借口的。
当我看到它逐渐蔓延到其他语言(C#,Python)中时,它真的让我感到不安。
第三种选择-完全禁止在条件内分配:
在高可靠性的情况下,不允许我们(在前面的注释中没有给出充分的解释)在条件语句中分配变量,从而完全消除了此问题,因为我们可以在编译器中或者使用LINT将其关闭,并且仅在非常受控制的情况下才可以使用我们允许使用它。
请记住,无论赋值是发生在条件内部还是外部,通常都会生成相同的代码,这只是减少代码行数的捷径。规则总是有例外,但是它不必一定是有条件的,如果需要,我们总是可以写出自己的方式。
因此,另一种选择仅仅是禁止此类语句,并在需要的地方使用注释来关闭LINT检查此常见错误。
-亚当
我使用(i == 0)的原因很简单,因为它读起来更好。它使我的头部非常顺畅。当我们将代码通读回去进行调试或者其他用途时,它的流动就像读一本书一样,更加有意义。
所有编码标准的规则0应该是"编写易于被其他人阅读的代码"。因此,我接受(最迅速变化的值)测试反对(最不迅速变化的值或者常数),即在这种情况下为" i == 0"。
即使在此技术有用的情况下,规则也应"避免在比较的左边放一个左值",而不是"总是在左边放一个常数",这通常是这样解释的,例如,从写作中获得
if (DateClass.SATURDAY == dateObject.getDayOfWeek())
如果getDayOfWeek()返回一个常量(因此不是左值)!
我很幸运(至少在这方面),因为这些天我主要使用Java进行编码,并且如上所述,如果(someInt = 0)无法编译。
关于比较两个布尔值的警告有点像是一团糟,因为在大多数情况下,我们或者比较两个布尔变量(在这种情况下将它们互换就无济于事),或者测试是否设置了一个标志,而后生-如果我发现我们在条件中将任何内容显式地与真或者假进行了比较,则请放下我们! rr!
我曾经确信,更具可读性的选项(i == 0)是更好的选择。
然后,我们遇到了一个生产错误(不是我的幸好),这里的问题是($ var = SOME_CONSTANT)类型的错误。客户开始收到发给其他客户的电子邮件。敏感类型数据也是如此。
我们可以争辩说Q / A应该抓住了它,但事实并非如此,那是另一回事了。
从那天开始,我一直在努力争取(0 == i)版本。它基本上消除了问题。感觉不自然,所以请我们注意,不要犯错。根本没有办法在这里弄错它。
与某人不小心在if中分配值相比,发现某人没有在代码检查中反转if语句要容易得多。如果格式是编码标准的一部分,人们会寻找它。人们通常不会在代码审查期间调试代码,并且眼睛似乎会在(i = 0)与(i == 0)上进行扫描。
我还是Java" Constant String" .equals(dynamicString)的忠实粉丝,没有null指针异常是一件好事。
在C语言中,是的,但是我们应该已经打开所有警告并进行了无警告编译,许多C编译器将避免此问题。
我很少看到可读性POV带来很多好处。
对于大于几百行的代码,代码的可读性是最重要的事情之一,并且绝对i == 0的读取比反向读取要容易得多
if(DialogResult.OK == MessageBox.Show("Message")) ...
我总是建议以这种方式编写比较。如果MessageBox.Show(" Message")的结果可能为空,那么如果进行相反的比较,则我们可能会面临NPE / NRE的风险。
在包含NULL的世界中,数学和逻辑运算不是自反的。