boolean_variable == falseよりも!boolean_variableを使用する理由


60

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


28
書くのが短くなります。
ゼノン

39
それはやるようなものboolean == trueです:それは意味がありません。ifステートメント内の式は、それだけです:式。既にブール式に評価されているものがある場合、それを強制的に評価するチェックを追加するのはなぜですか?
Maxpm

10
@zzzzBov:ええ、いいえ。これは、ほとんどの(Cスタイルの)プログラマーが行う方法ではありません。
アマラ

9
@zzzzBov:コメントはあいまいです。あなたがそれ!boolean_variableがほとんどのCプログラマーがそれを行う方法であるということであれば、私は同意します。
キーストンプソン

29
そしてもっと重要なのは、どうして誰も書きたくないのboolean != trueですか?

回答:


153

のような行を見るとき if (!lateForMeeting())「会議に遅れない場合」と読みますが、これは理解するのは非常に簡単ですが、「会議に遅れるという事実が偽である場合」if (lateForMeeting() == false)とは対照的です"

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


27
+1 Pythonでは、実際に次のように記述しますif not late_for_meeting:)
phunehehe

42
「___がfalseの場合」が「___でない場合」よりも自然に聞こえる場合、___の名前を改善する必要があると私は考えます。
マイクデシモーネ

12
Perlでは次のように書くことができますunless late_for_meeting
ヘンリック・リッパ

4
@HenrikRipa:あなたがタイプできるものは、Perlで合法なコードであるように思えます。それがあなたが望むことをするかどうかは別の質問です;)
アダムロビンソン

4
@ A-Cubeそもそもそのようなメソッドはありません。代わりに、というメソッドがありdone()ます。ダブルネガは悪いです。
kba

97

書く== false== true冗長です。それはまた、任意の極限に持って行くことができます。書き始めたら

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

それではなぜ

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

またはどうして

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

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


これを考えていませんでした!
エル

51
== falseは冗長ではなく、より冗長です!。OTOH == trueは冗長です。
dan04

4
@ dan04そのとおりです。しかし、私が意図した意味では、それは悪い考えのままです。(exp1 != exp2)対を検討してください((exp1 == exp2) == false)。確かに、これらは不自然なシナリオですが、それでも、trueまたはfalseとの明示的な比較を記述することはほとんどありません。演算子を使用するのと同じように!=!
アンドレスF.

26
@ dan04:言語がすでに提供して!いる場合は冗長です。
-DeadMG

5
@ dan04:書くたびにbool_expression == bool_literal、それ== ...は冗長です。真偽をテストするかどうかは関係ありません。これは、結果/代替ブロックの順序の変更にすぎません。Andresの例は、この点を完全に示しています。ほとんどの最新のコンパイラーは、冗長性を最適化しますが、それでも冗長です。
Lèsemajesté

70

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

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

この意味は

if (cond)

そして

if (cond == true)

同じことを意味しないでください。がcondゼロ以外の場合、最初は真です。2番目はtrue、Cで(もしあれば#include <stdbool.h>)単純に等しい場合にのみ真です1

たとえば、でisdigit()宣言された関数は、引数が数字の場合は値を<ctype.h>返し、数字でない場合はゼロ以外を返します。条件が真であることを示すために戻ることができます。比較は失敗します。int04242 == true

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

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

他の言語の中には、cond == trueand cond == false(または構文が何であれ)が安全であるような、より優れた振る舞いのブール値と呼ばれるものがあります。それでも、私が見たすべての言語にはnotor !演算子があります。そこにあるので、あなたもそれを使うかもしれません。使用するcond == falseのではなく、!condまたはnot cond、私の意見では、読みやすさを改善しません。(!キャラクターが一目で見るのが難しいことは事実です!。これを避けるために、後にスペースを追加することがあります。)

また、多くの場合、コードをわずかに再配置することにより、問題回避し、明確性向上させることができます。たとえば、次のように:

if (!cond) {
    do_this();
}
else {
    do_that();
}

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

if (cond) {
     do_that();
}
else {
    do_this();
}

それは常に良いとは限りませんが、チャンスがある場所を探すのに害はありません。

概要: CおよびC ++では、等価比較にtruefalse危険である、過度に詳細な、と貧しいスタイル。他の多くの言語では、このような比較は危険ではないかもしれませんが、それでもまだ過度に冗長でスタイルが悪いです。


+1は、実際の有用な技術的説明を含む1つの答えです。
マイクナキス

プログラミング言語に関係なく、私は今でもこのように考えています== true。そのほうが気分がいい。
ダーバル

1
@Dervall:単にそうではない何かを仮定するのも良くありません。ブール値の等価比較は安全が、実際には適切ではないだけで、特定の言語でのいくつかのコーナーケースがありますが、双方向型推論との強い暗黙のキャストフリー型システムを持っているハスケル、で例えば、1は書き込み可能性がある(==True) . fことを明確にします-> Boolreturn-polymorphic function のインスタンス化が必要ですf。それはnot . not . f、より明確であり、厄介ではありません(f :: a -> Bool)
左辺約

また、pred(x)==pred(y)boolを返す関数のようなものを実行することは確かに適切predです。代替案pred(x)? pred(y) : !pred(y)は、ほとんど受け入れられないことに同意するものです。
左辺約

1
@leftaroundabout:それを知っていpred(x)pred(y)、同じ値を使用して真理を表す場合は問題ありません。これは、一部の言語では安全な仮定ですが、他の言語ではそうではありません。たとえば、Cでは、と書くことができます!!pred(x) == !!pred(y)
キーストンプソン

14

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

私が使用する主な理由== false!、コードを見たときに見落としがちすぎることです。

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


オペレーターがnotPascalのように命名されていたら、これが問題になるとは思いません。


5
このまさに理由で、いくつかの医療機器ソフトウェアのために私が取り組んでいたC ++プロジェクトに== false!、この同じ理由ではなく(それを際立たせるために)義務付けられたコーディング標準がありました。ただし== true、を使用する必要はなかったため、ゼロ以外の値は正常に機能しました。
tcrosley

12
私はいつもこの議論に納得がいかないことを発見しました-C / C ++ / C#/ Java / etcには、単一の文字を見落とすことがコードの解釈に同様に重要な影響を与える他の場所があります。「!」唯一の悪いものは私には意味がないので。
ベヴァン

5
@bevanどうやらまだ噛まれていないようです。

1
見落とし!はおそらくこの種の最も厄介な間違いであることに同意しますが、これはIMOが書く習慣を作るのでは==falseなく、より良い単体テストを書くことを引き起こすべきです。
左辺約

8
@ThorbjørnRavnAndersenまったく逆です-私は長年にわたって十分な頻度で噛まれてきたので、すべての文字読むように自分自身に教えてきました。私は毎日読む必要があるコードのすべて(またはほとんど)の著者ではないので、ここで説明している個人的な慣習には最小限の価値があります:読んだすべてのコードを正しく理解する必要がありますが、私が書いたものだけ。
ベヴァン

13

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

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

それと比較してください

太陽が輝いていない場合、私は家にいます。

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

が必要な言語では!、演算子とオペランドの間にスペースを入れます。これにより、否定が見逃しにくくなります。

if (! condition) { … }

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



6

なぜなら、あなたはboolean = false(明らかなエラーを伴って)書くかもfalse == booleanしれず、自然に見えないかもしれないからです(たとえそれがどんなに良い練習であっても)


昔、私が最初にプログラミングを始めたとき、私の指導者は、そのif( INVALID_HANDLE_VALUE == hFile )ようなことを避けるためにやる習慣を身につけるよう提案しました。そうすれば、スリップして2つではなく1つの等号を使用すると、コンパイラエラーが発生します。明らかにこれは、left-expressionが定数の場合にのみ機能しますが、数え切れないほどの頭痛の種を減らしました。
ドリューチャピン

静的解析ツールを使用すれば、頭痛の種を100倍も節約でき、自然なhFile==INVALID_HANDLE_VALUE 書き方を復元できます。
Gqqnbig

4

if (!boolean_variable)に変換しif the condition is not trueます。

if (boolean == false)に変換しif the condition not false is trueます。これは逆論理であるため、理解するのが難しくなります。


3
!trueは、trueではないことを意味します。!booleanは、ブール値の値に応じてfalse または trueではないことを意味します。ブール値自体は論理的な反転です。
S.ロビンズ

1
@ S.Robinsブール変数の愚かなブール名を見つけました。たとえば、次のようなisVisibleものがより良い例です。次に、if (!isVisible)表示されていない場合は-を理解するのが簡単if (isVisible==false)で、逆論理です。今より明確になってほしい。または、あなたのコメントを誤解しましたか?
ブジェリシュ

2

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

そうは言っても、新しいコンパイラーはこれをなくすと信じているので、どちらでも構いません。


マシンコードの生成はコンパイラの仕事であり、高級言語のプログラマの仕事ではありません...
CVn

歴史的な理由から、これは、ある方法が他の方法よりも好まれた理由の1つである可能性が非常に高いです。
レゴラス

1

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

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

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

私は本当にどちらの方法も気にしません。


4
その場合value == true、それがnullでないことを確認する理由はありません。場合value == nullには、最初の場所でのif文をトリガーすることはありませんので、if (value)十分なものでなければなりません。
zzzzBov

1
ブール値は(javaでは)オブジェクトであるため、nullになる可能性があるため、単にif (value)例外をスローします。賛成票を投じる人が理由を挙げてくれれば幸いです。
WuHoUnited

3
私はたまたまこれを見ただけでした。ブール値のnullはお勧めできません。どうして?ブール値は通常、オン/オフを切り替えるものの状態を表すためです。ほとんどの場合、最初にfalseを宣言し、動作に合わせて変更する必要があります。ブール値が初期化されていないことは非常にまれです。
berg子

私はここでオーバージーンに同意する必要があります。私自身、boolを初期化せずにnullをチェックするという悪い癖(特にJavaの場合)に陥りました。私はこれが言語の欠陥であると思いますが、ユーザーにその欠陥を課します。私の意見では、新しいbool変数を宣言するとき、初期化せずにデフォルトでfalseにすべきです。

2
@WuHoUnitedは、値がnullであってvalue == trueも十分です。
zzzzBov

1

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

C / C ++ / Java /などの場合 プログラマ、「!」の意味 演算子は完全に同化されており、見たときに自動的に心に「ない」ことがあります。持っていることif (!isOpen)if (_NOT_ isOpen)私と同じくらい明確です。ただし、C / C ++では、でマクロを作成できます#define _NOT_ !。しかし、私を信頼してください、数年後にこれは完全に不必要です。

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


C ++はすでに「not」を理解しているため、提案するC ++マクロを作成する必要はありません。関連:stackoverflow.com/questions/2393673/c-and-or-not-xor-keywords
frozenkoi

それは本当ですが、それはC ++ 0X標準のみのキーワードです。その前は、単なるマクロでした。
ファビオセコネロ

0

サイズが重要です;)

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

boolean1 = false
boolean2 = true

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

そして、特に大きな違いがあるルビーの例:

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

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


0

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

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


0

変数に適切な名前を付けた場合、!booleanより自然です。それnot booleanは、コードを精神的に読むのに十分なプログラマーであるすべての人について読みます


0

一部の人々にとっては、意味が早く表現されるほど良い。

「if!...」を持っている人は、「if ...」と比較して速くなり、条件全体を読む必要があります(実際にはかなり長い場合があります。たとえば(thisThing = thatThingまたはsomething =その他)OR(最後に== falseを見つけるためだけに、thinga = thingbおよびthinga = thingd)など)。

を持っている!(私は実際、言語が許すときはnotを好む)すぐに、この状態に対してすぐに英語の 'not'を得る。

また、この問題はuntil、それをサポートする言語での使用を検討することにつながります。たとえば、物事が完了するまで「一般的なこと」を行います。他の人が言うように、自然言語表現が目標です。上記の「太陽が輝いている」例が好きです。


0

別の理由は、複数の言語を使用するコードベースで作業している場合、すべての言語で安全な何かを行うための慣用的な方法があるなら、あなたが良い習慣を形成するようにそれをどこでもそのように行うことはかなり良い考えだからですつまずく可能性が低くなります。

私はどこでも考えることができませんif (!variable)(またはif not variableあなたの言語に応じたものなど)は安全ではありませんが、例えばif self.is_ready() == False: ...Pythonがself.is_ready()returns None、現在または将来の場合は安全ではありません。Noneと同様に偽であるため、準備ができていなかったことを示しますFalse

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.