22

好的,我们知道下面两行是等价的——

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

此外,过去鼓励使用第一种方法,因为如果您不小心使用了“=”而不是“==”,编译器会给出错误消息。

我的问题是——在当今这一代非常漂亮的 IDE 和智能编译器中,您仍然推荐第一种方法吗?

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

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

在我看来,我永远不会推荐上述内容。有没有第二意见?

4

28 回答 28

74

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

于 2008-09-29T11:23:50.373 回答
21

在 C# 中将变量放在第一位还是最后都没有关系,因为赋值不会计算为 bool(或可转换为 bool),因此编译器会捕获任何错误,例如“if (i = 0) EntireCompanyData.Delete( )"

因此,至少在 C# 世界中,这是一种风格问题,而不是绝望。并且把变量放在最后对于说英语的人来说是不自然的。因此,对于更具可读性的代码,变量优先。

于 2008-09-29T11:26:14.407 回答
12

如果您有一个无法通过开关很好地表示的 if 列表(可能是由于语言限制),那么我宁愿看到:

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

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

特别是,在 Java 中,我发现这样做很有用:

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

因为 someString 可能为 null,这样你就永远不会得到 NullPointerException。如果您将知道永远不会为空的常量与可能为空的对象进行比较,这同样适用。

于 2008-09-29T11:25:10.073 回答
9
  1. (0 == 我)

我会一直选这个。确实,当今大多数编译器都不允许在条件语句中分配变量,但事实是有些编译器允许。在今天的网络编程中,我必须在系统上使用无数种语言。通过使用 0 == i,我始终知道条件语句是正确的,并且我不依赖编译器/解释器来为我捕捉错误。现在,如果我必须从 C# 跳转到 C++ 或 JavaScript,我知道我不必在我的代码中跟踪条件语句中的赋值错误。对于这么小的东西并让它节省大量时间,这是不费吹灰之力的。

于 2008-09-29T12:24:28.217 回答
8

我曾经坚信更具可读性的选项(i == 0)是更好的选择。

然后我们遇到了一个生产错误(幸好不是我的),问题是 ($var = SOME_CONSTANT) 类型的错误。客户开始收到本应发送给其他客户的电子邮件。敏感类型数据也是如此。

你可以争辩说 Q/A 应该抓住它,但他们没有,那是另一回事。

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

发现有人在代码审查中没有反转 if 语句也比有人不小心在 if 中赋值要容易得多。如果格式是编码标准的一部分,人们就会寻找它。人们通常不会在代码审查期间调试代码,并且眼睛似乎会扫描 (i = 0) 和 (i == 0)。

我也是 java "Constant String".equals(dynamicString) 的忠实粉丝,没有空指针异常是一件好事。

于 2008-09-29T15:29:03.093 回答
7

你知道,我总是使用条件的if (i == 0)格式,我这样做的原因是我用 C# 编写了我的大部分代码(无论如何都会标记另一个代码)并且我先进行测试无论如何,我的开发方法和测试通常都会发现这个错误。

我曾在他们试图强制执行 0==i 格式的商店工作过,但我发现它写起来很尴尬,记起来也很尴尬,而且它最终成为了那些正在寻找低垂果实的代码审查者的饲料。

于 2008-09-29T11:49:40.937 回答
6

实际上,DialogResult 示例是我推荐这种风格的地方。如果可以看到,它将 if() 的重要部分放在左侧。如果它在右侧并且 MessageBox 有更多参数(很可能),您可能需要向右滚动才能看到它。

OTOH,我从未见过“(0 == i)”风格有多大用处。如果你记得把常数放在前面,你可以记得使用两个等号,

于 2008-09-29T11:26:25.187 回答
6

我一直在尝试使用第一种情况(0==i),这几次救了我的命!

于 2008-09-29T11:57:10.793 回答
3

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

我绝对不会要求程序员长大。

于 2008-09-29T11:21:57.477 回答
3

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

“嗯?”,你想。

好吧,如果我有意识地决定在左侧放置一个左值,那么我会充分注意我正在输入的内容,以注意我是否为“==”输入了“=”。我希望。在 C/C++ 中,我通常将 -Wall 用于我自己的代码,这会在 gcc 上为大多数“=”生成警告,因为“==”错误无论如何。我不记得最近看到过那个警告,也许是因为我编程的时间越长,我对以前犯过的错误就越本能地偏执……

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

对我来说似乎被误导了。诀窍的重点是避免意外分配给某些东西。

但是谁能说 DialogResult.OK 是否比 MessageBox.Show("Message") 更可能评估为可分配类型?在 Java 中,方法调用不可能是可分配的,而字段可能不是最终的。因此,如果您担心为 == 键入 =,那么对于这个示例,在 Java 中实际上应该是相反的。在 C++ 中,两者都不能赋值。

(0==i) 之所以有用,是因为您绝对确定数字文字永远不可分配,而 i 可能是。

当比较的双方都是可分配的时,您无法以这种方式保护自己免受意外分配的影响,而当您不知道哪个是可分配的而不查找时也是如此。没有魔术说“如果你把它们放在反直觉的地方,你就会安全”。虽然我认为它引起了人们对这个问题的关注,就像我的“总是打破规则”规则一样。

于 2008-09-29T11:45:30.290 回答
3

我使用 (i == 0) 的原因很简单,因为它读起来更好。它在我的脑海中产生了非常流畅的流动。当您出于调试或其他目的将代码通读给自己时,它就像阅读一本书一样简单,而且更有意义。

于 2008-09-29T12:49:06.237 回答
2

我的公司刚刚从其编码标准中删除了执行 if (0 == i) 的要求。我可以看到它是多么有意义,但在实践中它似乎倒退了。有点遗憾的是,默认情况下 C 编译器可能不会给你一个关于 if (i = 0) 的警告。

于 2008-09-29T11:25:10.417 回答
2

第三个选项 - 完全禁止在条件内赋值:

在高可靠性情况下,不允许(在前面的注释中没有很好的解释)在条件语句中分配变量 - 它完全消除了这个问题,因为您要么在编译器处关闭它,要么使用 LINT 并且仅在非常受控的情况下你可以使用它吗?

请记住,无论赋值发生在条件内部还是外部,通常都会生成相同的代码——这只是减少代码行数的捷径。规则总是有例外,但它永远不必在条件中 - 如果需要,您总是可以写出自己的方式。

因此,另一种选择只是禁止此类语句,并在需要时使用注释关闭 LINT 检查此常见错误。

-亚当

于 2008-09-29T12:38:30.100 回答
1

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

于 2008-09-29T11:24:04.490 回答
1

就我个人而言,我不喜欢(1)并且总是喜欢(2),但是在处理对话框和其他可能超长的方法时,为了可读性而反转。它看起来并不坏,但是如果您将 MessageBox 扩展到它的全长。您必须一直向右滚动才能确定返回的结果类型。

因此,虽然我同意您关于值类型的简单比较的断言,但我不一定认为它应该成为消息框之类的规则。

于 2008-09-29T11:24:37.673 回答
1

两者都是相等的,尽管我更喜欢 0==i 变体。

比较字符串时,比较 "MyString".equals(getDynamicString()) 更容易出错

因为, getDynamicString() 可能会返回 null。为了更稳定,写 0==i

于 2008-09-29T11:27:57.383 回答
1

好吧,这取决于所讨论的语言和编译器。上下文就是一切。

在 Java 和 C# 中,除了比较两个布尔值的极少数情况外,“赋值而不是比较”拼写错误最终会导致无效代码。

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

在我看来,第二种形式(变量然后是常量)更具可读性——所以在任何绝对不会引起问题的地方,我都会使用它。

于 2008-09-29T11:42:43.260 回答
1

所有编码标准的规则 0 应该是“编写其他人可以轻松阅读的代码”。出于这个原因,我使用(最快速变化的值)测试(不太快速变化的值或常数),即在这种情况下为“i == 0”。

即使这种技术很有用,规则也应该是“避免将左值放在比较的左边”,而不是“总是把任何常量放在左边”,这就是它通常的解释方式——例如,什么都没有从写作中获得

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

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

我很幸运(至少在这方面),因为这些天我主要使用 Java 进行编码,并且如前所述,如果 (someInt = 0) 不会编译。

关于比较两个布尔值的警告有点像红鲱鱼,因为大多数时候你要么比较两个布尔变量(在这种情况下交换它们没有帮助),要么测试是否设置了一个标志,结果很糟糕-betide-如果我发现您在条件句中将任何内容与真假进行了明确的比较!呸!

于 2008-09-29T13:09:42.350 回答
1

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

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

于 2008-09-29T15:32:26.967 回答
1

对于大于几百行的代码,代码可读性是最重要的事情之一,而且绝对 i == 0 比相反的更容易阅读

于 2008-09-29T16:33:29.800 回答
0

也许不是你的问题的答案。我尝试使用 === (检查是否相同)而不是相等。这样就不会进行类型转换,它会强制程序员确保传递了正确的类型,

于 2008-09-29T11:24:26.957 回答
0

您说得对,将重要组件放在首位有助于提高可读性,因为读者倾向于主要浏览左列,将重要信息放在那里有助于确保它会被注意到。

但是,永远不要对同事低头说话,即使是开玩笑也暗示这将是你的行为不会让你在这里得到高分。

于 2008-09-29T11:24:43.367 回答
0

我总是选择第二种方法。在 C# 中,编写

if (i = 0) {
}

无论如何都会导致编译器错误(无法将 int 转换为 bool),因此您可能会犯错误实际上并不是问题。如果您测试布尔值,编译器仍会发出警告,您不应将布尔值与真或假进行比较。现在你知道为什么了。

于 2008-09-29T11:27:23.750 回答
0

我个人更喜欢使用变量-操作数-值格式,部分原因是我使用它的时间很长,以至于感觉“自然”,部分原因是它似乎是占主导地位的约定。有一些语言使用赋值语句,例如:

:1 -> x

因此,在这些语言的上下文中,即使它是有效的,看到以下内容也会变得非常混乱:

:if(1=x)

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

于 2008-09-29T12:12:22.190 回答
0

这是我最大的烦恼之一。没有理由降低代码的可读性(如果 (0 == i),什么?0 的值如何变化?)以捕捉过去 20 年编写的任何 C 编译器都可以自动捕捉的东西。

是的,我知道,大多数 C 和 C++ 编译器默认情况下不会打开它。查找正确的开关以将其打开。没有理由不了解您的工具。

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

于 2008-09-29T12:36:35.020 回答
0

我相信唯一会迫使一个人超越另一个的因素是,如果工具链没有提供警告来捕捉表达式中的赋值。我作为开发人员的偏好无关紧要。通过清晰地呈现业务逻辑来更好地服务于表达式。如果 (0 == i) 比 (i == 0) 更合适我会选择它。如果不是我会选择另一个。

表达式中的许多常量由符号名表示。一些风格指南还限制了可用于标识符的词性。我使用这些作为指导来帮助塑造表达式的阅读方式。如果生成的表达式读起来像伪代码一样松散,那么我通常会很满意。我只是让表达自己表达,如果我错了,它通常会在同行评审中被抓住。

于 2012-06-26T21:40:52.910 回答
-1

我们可能会继续谈论我们的 IDE 有多好,但我仍然对降低 IDE 警告级别的人数感到震惊。

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

于 2008-09-29T12:00:57.553 回答
-3
if(DialogResult.OK == MessageBox.Show("Message")) ...

总是建议以这种方式编写比较。如果 MessageBox.Show("Message") 的结果可能为空,那么如果比较是相反的,那么您将面临 NPE/NRE 的风险。

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

于 2009-06-16T05:02:45.850 回答