web-dev-qa-db-ja.com

boolean_variable == falseではなく!boolean_variableを使用する理由

この質問へのコメント: メソッドがfalseを返すかどうかを確認:結果を一時変数に割り当てるか、メソッド呼び出しを条件付きで直接配置しますか? は、条件をテストするときに!booleanではなくboolean == falseを使用する必要があると述べています。どうして?私にとって、boolean == falseは英語でははるかに自然で、より明確です。これが単なるスタイルの問題だとすみませんが、この!booleanの設定に他の理由があるのか​​どうか疑問に思っていました。

62
ell

if (!lateForMeeting())のような行が表示されたら、それを"会議に遅れない場合"と読みます。これは、if (lateForMeeting() == false)とは対照的に、非常に簡単に理解できます。これは"会議に遅れているという事実が偽の場合"と読みます。

それらは同じ意味ですが、前者は同等の英語の文がどのように構成されるかにより近いです。

158
kba

== falseおよび== trueの記述は冗長です。それはまた、任意の極端に取ることができます。書き始めたら

if (condition == false) { ... }

その後、なぜ

if ((condition == false) == true) { ... }

またはなぜしない

if ((someExp == anotherExp) == true) { ... }

この話の教訓は、conditionがブール式の場合、== falseを追加する必要がないことです。これが!の演算子です;)

99
Andres F.

Cおよびいくつかの類似した言語では、ブール式をfalseまたはtrueと等しいかどうか比較するのは危険な習慣です。

Cでは、任意のスカラー式(数値またはポインター)をブールコンテキストで、たとえばifステートメントの条件として使用できます。 Cの規則では、if (cond)if (cond != 0)と同等です-つまり、ゼロはfalseであり、anyゼロ以外の値は真です。 condがポインター型の場合、_0_はNULLポインター定数として扱われます。 if (ptr)if (ptr != NULL)を意味します。

この意味は

_if (cond)
_

そして

_if (cond == true)
_

同じことを意味しないcondがゼロ以外の場合、最初は真です。 2番目は、それがtrueと等しい場合にのみ当てはまります。Cの場合(_#include <stdbool.h>_がある場合)は単に_1_です。

たとえば、_<ctype.h>_で宣言されているisdigit()関数は、int値を返します。引数が数字の場合は_0_、そうでない場合はゼロ以外を返します。 _42_を返し、条件が真であることを示すことができます。 _42 == true_の比較は失敗します。

_0_がfalseと見なされる唯一の値であるため、falseと等しいかどうかの比較が機能します。 if (!cond)if (cond == false)は同じことを行います。ただし、それを利用する場合は、falseとの比較は問題なく、trueとの比較は問題であることを覚えておく必要があります。さらに悪いことに、trueと比較すると機能しますほとんどの場合(たとえば、等価演算子と関係演算子は常に_0_または_1_)。これは、これを使用して導入したバグを追跡するのが難しい場合があることを意味します。 (心配する必要はありません。重要なクライアントにコードをデモするとすぐに表示されます。)

C++にはわずかに異なる規則があります。たとえば、そのbool型は言語により密接に統合されており、if (cond)condを型boolに変換します。しかし、効果は(ほとんど)同じです。

他の一部の言語には、_cond == true_および_cond == false_(または構文が何であれ)が安全であるような、より適切に動作するブール値があるものがあります。それでも、私が見たすべての言語にはnotまたは_!_演算子があります。それはそこにあるので、それを使うのもよいでしょう。 _cond == false_または_!cond_ではなく_not cond_を使用しても、可読性は向上しません。 (_!_文字が一目でわかりにくい場合があるのは事実です。これを回避するために、_!_の後にスペースを追加することがあります。)

そして、多くの場合、問題を回避しておよびコードをわずかに再配置することで明確さを改善できます。たとえば、以下ではありません。

_if (!cond) {
    do_this();
}
else {
    do_that();
}
_

あなたは書くかもしれません:

_if (cond) {
    do_that();
}
else {
    do_this();
}
_

それは常に良いとは言えませんが、それがある場所を探すのに害はありません。

概要: CおよびC++では、trueおよびfalseとの等価比較は危険であり、非常に冗長であり、スタイルが貧弱です。他の多くの言語では、そのような比較は危険ではないかもしれませんが、それでも過度に冗長であり、スタイルが貧弱です。

74
Keith Thompson

2つは機能的に同じなので、どちらを使用するかは好みの問題です。

[〜#〜] i [〜#〜]を使用する主な理由== falseは、私がそれを見つけたということです!コードを見たときに、見過ごすのが簡単すぎる。

これでひどく噛まれたので、私は偽りをテストするときにそれを非常に明確にする習慣をつけました。


Pascalのように演算子にnotという名前が付いていた場合、これが問題になるとは思いません。

14
user1249

condition == falseが本当に「英語ではるかに自然」である場合、私はあなたがネイティブスピーカーではないと想定しなければなりません。そうでなければnobodyはそのように話すので、これを説明することはできません:

太陽が輝いているなら、私は家にいます。

と比較して

太陽が輝いていなければ私は家にいます。

そうは言っても、単一の細い!文字はコードで簡単に見落とされることに同意します。そのため、言語でサポートされている場合は、キーワードnotを使用します。たとえばC++ doesはこれを許可しますが、多くのプログラマはこれを認識していません。

!を必要とする言語では、演算子とオペランドの間にスペースを入れます。これは否定を見落とすことをはるかに難しくします:

if (! condition) { … }

すべてのプログラマーは、これを自動的にと考え直さずに、頭の中で「条件付けなし」に変換する必要があることに注意してください。この種の流暢なコードイディオムの習得は、優れたプログラマになるための最初のステップの1つです。

13
Konrad Rudolph

時々boolean = false(明らかなエラーあり)およびfalse == booleanは自然に見えません(それがどれほど良い練習であっても)

7
ratchet freak

私が見るとき var == falsevarがブール値であるか、3つ以上の値(たとえば、maybeundefined、およびtrueおよびfalse、または IEEE 1164の9つの値 )のようなもの。

7
AProgrammer

if (!boolean_variable)は_if the condition is not true_に変換されます。

if (boolean == false)は_if the condition not false is true_に変換されます。それは逆論理なので、理解するのは難しいです。

4
BЈовић

(はるかに)古いコンパイラでは、(boolean == false)を2つのレジスタ割り当てと機械語の比較コードに分割すると思います。最初の例は、1つの割り当てとNOT演算子に分割されます。パフォーマンスの点では、比較演算は、比較されるレジスタのサイズに応じて、ビット単位の反転(1クロック)と比較して多くのクロックサイクルを要し、実行速度が遅くなります。

そうは言っても、新しいコンパイラーはこれを排除するので、どちらでもかまいません。

2
lcllam

真の条件をテストする場合、特にif (condition)を実行するのは理にかなっています。特に、「is」で始まるブール変数の命名規則を適用する場合は、if (isOpen)が完全に明確であり、 _!= false_の使用は冗長になります。

C/C++/Java/etcの場合。プログラマー、「!」の意味演算子は完全に同化され、私たちがそれを見ると自動的に「気にしない」ことになります。したがって、if (!isOpen)があることは、if (_NOT_ isOpen)と同じくらい明確です。しかし、十分に精通していません。C/ C++では、_#define _NOT_ !_を使用してマクロを作成できます。しかし、数年後、これは完全に不要です。

それはさておき、ブール値をリテラルと比較せずにテストすることが常に望ましいです。たとえば、if (x == true)をテストするのは危険です。ブール値がゼロでない場合はtrueと見なされ、リテラルtrueには特定の値が1つしかないため、xが「true」(つまりゼロ以外)でも、比較はfalseに評価されます(2が含まれ、リテラルtrueが1であるため)。もちろん、falseとの比較には適用されませんが、trueをテストするときに使用しない場合、なぜそれを使用するのか偽のテスト?

1
Fabio Ceconello

私の経験と、あなたがリンクした私の質問からの回答に基づいています。

一部の人々はif(condition)を使用することを好みます。理由は、書く方が短いからです。そして、私にとってはそれは実際に理にかなっています。たとえば(!isValidated())私はこれを「検証されていません」と読みました。しかし私にとってはすべて個人の好みに基づいており、trueまたはfalseを返すかどうかはisValidated()メソッドの論理構造に依存します

0
KyelJmD

変数に適切な名前を付けた場合、!booleanの方が自然です。 not booleanプログラマーがコードを読む精神的に十分な人なら誰にでも。

職場では、nullの可能性があるブール値を扱うことが多いため、このケースを次のようにコーディングします。

if (value != null && value == true) {
        //do something
}

個人的には対称性により読みやすくなると感じているからです。特に、テストされている他のブール値がある場合。

どちらにしてもかまわない。

0
WuHoUnited

サイズが重要です;)

混合式では、読みやすくなります。

boolean1 = false
boolean2 = true

p ! boolean1 and ! boolean2
p boolean1 == false and boolean2 == false

そして特にRubyの場合は大きな違いがある例です:

boolean = nil
p ! boolean         #-> true
p boolean == false  #-> false

nilは偽ではありませんが、真ではありません。

0
knut

もう1つの理由は、複数の言語を使用するコードベースで作業している場合、すべての言語で安全な方法を実行する慣用的な方法がある場合は、あらゆる場所でそのようにして、良い習慣を形成することをお勧めします。そしてつまずきそうにありません。

if (!variable)(または、言語によっては_if not variable_などの同等物)が安全ではない場所は考えられませんが、 python if self.is_ready() == False: ...が現在または将来的にNoneを返す場合、self.is_ready()は安全ではありません。これは完全に合理的なことですNoneFalseと同じように誤っているので、準備ができていないことを示すためです。

0
daphtdazz