为避免在IF条件下使用NOT运算符以使代码更易读,这是一个很好的做法吗?我听说if (doSomething())
比if (!doSomething()).
答案 0 :(得分:40)
这实际上取决于你想要完成的事情。如果你没有其他条款那么if(!doSomething())
似乎没问题。但是,如果你有
if(!doSomething()) {
...
}
else {
// do something else
}
我可能会颠倒这个逻辑来移除!
运算符并使if
子句更加清晰。
答案 1 :(得分:19)
作为一般性陈述,使你的if条件尽可能可读是好的。对于你的例子,使用!没关系。事情看起来像是
if ((a.b && c.d.e) || !f)
您可能想要执行类似
的操作bool isOk = a.b;
bool isStillOk = c.d.e
bool alternateOk = !f
然后你的if语句被简化为
if ( (isOk && isStillOk) || alternateOk)
它只是使代码更具可读性。如果你必须调试,你可以调试isOk变量集,而不必在范围内挖掘变量。它对处理NPE也很有帮助 - 将代码分解为更简单的块总是很好。
答案 2 :(得分:11)
不,在!
语句中使用if..then..else
运算符绝对没有错。
变量的命名,在您的示例中,方法是重要的。如果您正在使用:
if(!isPerson()) { ... } // Nothing wrong with this
然而:
if(!balloons()) { ... } // method is named badly
这一切都取决于可读性。始终瞄准最可读的东西,你不会出错。始终尝试保持代码连续,例如,查看Bill the Lizards answer。
答案 3 :(得分:4)
一般来说,!是一个非常好的和可读的布尔逻辑运算符。没有理由不使用它,除非你通过删除双重否定或应用摩根定律来简化。
!(!A) = A
或
!(!A | !B) = A & B
根据经验,保持布尔返回方法的签名符合惯例并符合约定。 @hvgotcodes提出的场景的问题当然是a.b和c.d.e不是非常友好的例子。假设您有一个航班预订申请的航班和座位类。然后预订航班的条件可能完全像
if(flight.isActive() && !seat.isTaken())
{
//book the seat
}
这个完全可读且易于理解的代码。您可以重新定义Seat类的布尔逻辑,并将条件重新定义为此。
if(flight.isActive() && seat.isVacant())
{
//book the seat
}
因此删除了!运算符,如果它真的困扰你,但你会发现这一切都取决于你的布尔方法的含义。
答案 4 :(得分:1)
如果你有选择的话,避免使用!-operator通常不是一个坏主意。一个简单的原因是它可能是错误的来源,因为它可能会忽略它。更具可读性:if(conditionA == false)在某些情况下。如果你跳过else部分,这主要起作用。 如果你有一个else-block,你不应该在if条件中使用否定。
除了像这样的组合条件:
if(!isA() && isB() && !isNotC())
在这里你必须使用某种否定来获得所需的逻辑。 在这种情况下,真正值得思考的是函数或变量的命名。 尝试命名它们,这样你就可以在简单的条件下使用它们而不会出现否定。
在这种情况下,您应该考虑isNotC()的逻辑,如果它有意义,可以用方法isC()替换它。
最后你的例子在可读性方面还有另一个问题,这个问题比是否使用否定更严重:代码的读者是否真的知道doSomething()何时返回true和false? 如果它是假的,它还是做了吗?这是一个非常常见的问题,读者最终会试图找出函数的返回值究竟意味着什么。
答案 5 :(得分:1)
试试这个
if (!(a | b)) {
//blahblah
}
与
相同if (a | b) {}
else {
// blahblah
}
答案 6 :(得分:0)
我之前从未听说过这个。
怎么样
if (doSomething()) {
} else {
// blah
}
优于
if (!doSomething()) {
// blah
}
后者更清晰简洁。
除了!运算符可以出现在复杂的条件中,例如(!a || b)。那你怎么避免呢?
使用!操作员在您需要时。