写不好:
if (b == false) //...
while (b != true) //...
总是更好地代写:
if (!b) //...
while (!b) //...
据推测,性能没有差异(或存在?),但你如何权衡两者之间的显性,简洁,清晰,可读性等?
为了限制主观性,我还要感谢来自权威编码风格指南的任何引用,这些引用总是更好或者在何时使用。
注意:变量名称b
仅用作示例,ala foo
和bar
。
答案 0 :(得分:61)
它不一定是坏的,它只是多余的。此外,实际的变量名称权重很多。我希望例如if (userIsAllowedToLogin)
以上if (b)
或更差if (flag)
。
关于性能问题,编译器会以任何方式对其进行优化。
更新:对于权威来源,我在Sun Coding Conventions中找不到明确的内容,但至少Checkstyle有一个SimplifyBooleanExpression
模块会对此发出警告。
答案 1 :(得分:46)
你不应该使用第一种风格。我见过人们使用:
if ( b == true )
if ( b == false )
我个人觉得很难阅读,但它是可以接受的。然而,我对这种风格的一个大问题是它会导致您展示的令人难以置信的反直觉的例子:
if ( b != true )
if ( b != false )
读者需要付出更多努力才能确定作者的意图。就个人而言,我发现包括对真或假的明确比较是多余的,因此更难以阅读,但那就是我。
答案 2 :(得分:32)
这很有趣。
就我个人而言,我发现if (!a) {
比if (a == false) {
更少可读(编辑:对我而言),因此在以后维护代码时更容易出错,并且我已经转换为使用后一种形式。
基本上我不喜欢逻辑运算的符号选择而不是单词(C对Pascal),因为 me a = 10 and not b = 20
读取比a == 10 && !(b==20)
更容易,但那就是它是在Java中的。
任何将“== false”方法放下来支持“!”的人显然从来没有长时间盯着代码而错过了感叹号。是的,你可以得到代码盲。
答案 3 :(得分:24)
你不应该使用第一种风格的最重要原因是因为这两种风格都是有效的:
if (b = false) //...
while (b = true) //...
也就是说,如果您不小心遗漏了一个字符,则创建一个赋值而不是比较。赋值表达式求值为已分配的值,因此上面的第一个语句将值false
赋给b
并计算为false
。第二个将true
分配给b
,因此无论您在循环内使用true
做什么,它始终会计算为b
。
答案 4 :(得分:11)
除了初学者编写的代码外,我从未见过前者;它始终是后者,我认为没有人真正被它迷惑。另一方面,我认为
int x;
...
if(x) //...
VS
if(x != 0) //...
更有争议,在这种情况下,我更喜欢第二个
答案 5 :(得分:7)
恕我直言,我认为如果你只是在"Is"
前面加上bool变量名,那么它将是不言而喻的,更有意义,然后,你可以删除与true
或{{1}的显式比较}}
示例:强>
false
等
答案 6 :(得分:5)
我更喜欢第一个,因为它更清晰。机器可以同样读取,但我尝试为其他人编写代码,而不仅仅是机器。
答案 7 :(得分:3)
我更喜欢漫长的方法,但我比较使用==
代替!=
99%的时间。
我知道这个问题是关于Java的,但我经常在语言之间切换,例如,在C#
中,与(forntntance)== false
进行比较可以帮助处理可空的bool类型。所以我得到了与true
或false
进行比较但使用==
运算符的习惯。
我这样做:
if(isSomething == false)
或if(isSomething == true)
但我讨厌这些:
if(isSomething != false)
或if(isSomething != true)
出于明显的可读性原因!
只要您保持代码可读,就没关系。
答案 8 :(得分:2)
就个人而言,我会重构代码,所以我没有使用否定测试。例如。
if (b == false) {
// false
} else {
// true
}
或
boolean b = false;
while(b == false) {
if (condition)
b = true;
}
恕我直言,在90%的情况下,代码可以重构,因此不需要进行否定测试。
答案 9 :(得分:2)
这是我在StackOverflow上的第一个答案,所以很好...... 最近在进行重构时,我注意到2个代码块几乎完全相同,但是使用了一个代码
for (Alert alert : alerts) {
Long currentId = alert.getUserId();
if (vipList.contains(currentId)) {
customersToNotify.add(alert);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
而另一个
for (Alert alert : alerts) {
Long currentId = alert.getUserId();
if (!vipList.contains(currentId)) {
customersToNotify.add(alert);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
所以在这种情况下,创建一个适用于这两种情况的方法是有意义的,使用boolean == condition
翻转含义
private void appendCustomersToNotify(List<Alert> alerts
List<Alert> customersToNotify, List<Long> vipList, boolean vip){
for (Alert alert : alerts) {
Long currentId = alertItem.getUserId();
if (vip == vipList.contains(currentId)) {
customersToNotify.add(alertItem);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
}
答案 10 :(得分:1)
在我看来,这简直令人讨厌。不过我会引起骚动。
答案 11 :(得分:1)
正常的准则是永远不要对布尔值进行测试。一些人认为额外的冗长增加了清晰度。添加的代码可能会帮助一些人,但每个读者都需要阅读更多代码。
今天早上,我已经失去了半小时才找到一个小虫。代码是
if ( !strcmp(runway_in_use,"CLOSED") == IPAS_FALSE)
printf(" ACTIVE FALSE \n"); else
printf(" ACTIVE TRUE \n");
如果用常规约定编码,我会看到它错误得多:
if (strcmp(runway_in_use, "CLOSED"))
printf(" ACTIVE FALSE \n"); else
printf(" ACTIVE TRUE \n");
答案 12 :(得分:1)
第一个(b == false)不赞成的原因之一是初学者通常没有意识到第二种选择(!b)是可能的。因此,使用第一种形式可能会指向布尔表达式和布尔变量的误解。这样,使用第二种形式已成为某种形式:当有人写这篇文章时,他/她可能会理解正在发生的事情。
我认为这导致差异被认为比实际更重要。
答案 13 :(得分:0)
我会说这很糟糕。
while (!b) {
// do something
}
比
读得更好while (b != true) {
// do something
}
答案 14 :(得分:0)
虽然两者都是有效的,但在我看来,第一种感觉就像是类型错误。
对我来说b == false
和(i == 0) == false
一样错误。就像:是吗?
布尔值不是具有2个可能值的枚举。您不比较它们。布尔是谓词,表示某些事实。它们具有特定的运算符,例如&
,|
,^
,!
。
要反转表达式的真值,请使用运算符“!”,将其发音为“ not”。
使用适当的命名,它自然而然:!isEmpty
读为“ not is not empty”,对我来说很容易理解。
isEmpty == false
读到类似“它为空是错误的”之类的东西,我需要更多时间来处理。
答案 15 :(得分:0)
我不会详细介绍所有细节,因为很多人已经正确回答了。
功能方面,它给出了相同的结果。
就样式而言,这是一个偏好问题,但我确实相信 !condition
更具可读性。
对于性能的争论,我看到很多人说这没有区别,但他们没有任何理由证明他们的主张。让我们更深入一点。那么当你比较它们时会发生什么?
首先,逻辑上:
if(condition == false)
在这种情况下,if
正在将其要执行的期望值与必须计算的括号之间的值进行比较。
if(!condition)
在这种情况下,if
直接与条件的相反 (NOT) 进行比较。所以不是 2 次比较,而是 1 次比较和 1 次 NOT 运算,这样更快。
我当然不会在没有测试的情况下就这么说。这是我所做的测试的快速屏幕截图。 !condition
在超过 1000 万次迭代时几乎快两倍。
https://imgur.com/a/jrPVKMw
编辑:我在 C# 中测试了这个,用 Visual Studio 编译。一些编译器可能更聪明并对其进行了适当的优化,这会使性能保持不变。