if( 'constant' == $ variable)vs. if($ variable == 'constant')


49

最近、私はPHPで、特にWordPressフレームワーク内で多くのことをしています。私は次の形式の多くのコードに気付いています:

if ( 1 == $options['postlink'] )

期待していた場所:

if ( $options['postlink'] == 1 )

これは特定の言語/フレームワークで見られる慣習ですか?前者のアプローチが後者よりも好ましい理由はありますか(処理の観点、または構文解析の観点、あるいは人間の観点からも)

それとも単に好みの問題ですか?ある定数に対してテストされる変数項目は左側にあると、テストを実行するときは常に良いと思っていました。「チョコレートがケーキの場合」よりも、「ケーキがチョコレートの場合」という自然言語での質問の方がよく似ているようです。


1
私は決してそのようなコードを書くことはありませんが、公平にするために「もしチョコレートがケーキの味なら」は自然に聞こえます。自然言語はより柔軟です。
リックスラッドキー

4
@Rick言語では自然に聞こえるかもしれませんが、そのようなコードを見たときに、それが何をしようとしているのかを考えるために最初に停止する必要があることを否定することはできません。
エドガーゴンザレス

4
@Edgar Gonzalez:同意しました。コードでは固く反対しています。
リックスラッドキー

3
Code Complete 2nd Editionの第19章(「ブール式:ブール式の一般的な問題」セクション)は、実際にこのプラクティスを推奨しています。 。
CraigTP

4
私はよくこれらを「ヨーダ条件」と呼ばれるのを見ました
ブライアン

回答:


84

これを行う主な理由(いわゆる「ヨーダ条件付き」)は、偶発的=に等価比較演算子(==)の代わりに割り当て演算子()を使用することによる事故を防ぐためです。

つまり、次のことを間違えた場合:

$foo = 5;
if ($foo = 1) {
  // Stuff
}

ステートメントはtrue(または、PHPなどの一部の言語の場合は真の値)と評価され、見つけにくいバグが発生します。

しかし、あなたがした場合:

$foo = 5;
if (1 = $foo) {
  // Stuff
}

$foo整数に割り当てることができないため、致命的なエラーを受け取ります。

しかし、あなたが指摘したように、一般的に順序を逆にすると物が読みにくくなります。そのため、多くのコーディング標準(ただし、WordPressを含むすべてではない)は$foo == 1、のバグハンティングの利点にもかかわらず、提案または要求しています1 == $foo

一般に、私のアドバイスは、確立されたコーディング標準があればそれに従うことです。WordPressの場合、それはYoda条件を使用することを意味します。

存在せず、仲間とコンセンサスを介してそれを確立することが不可能な場合、それはディーラーの選択です。


2
言語を設計するとき(かなり前)、この種の問題を回避するために、:===等価性テスト用の)割り当て演算子を具体的に作成したことを覚えています。
ドナルドフェローズ

7
私は多くのコード行を書きましたが、の代わりに誤ってタイプしたことはありません。違いはどこでも強調されているので、混乱することはありません。一方、私は混乱を招いたり、理解するのが難しいコードをたくさん読んでいます。そのため、読みやすさを優先します:)。とにかく、良い答え。===
crazy2be

5
使用するさらに別の正当な理由-Wall -Werrorまたはコンパイラ/インタープリターの同等物。条件内の割り当てが正しい場合はもちろん、読みやすくする場合はほとんどありません。多くの言語では許可されていません。
カールビーレフェルト

7
知識:一部の言語ではif($foo = 1)評価さtrueれますが、PHPでは代わりに1に評価されます。if($foo = 20)20と評価されます。if($foo = 0)0と評価されますが、これは他とは異なり偽です。これにより、「複雑さのない別のレイヤー全体をバグに追加できる」
チャールズ

2
:実際には、WordPressはヨーダ条件文のための基準DOESコールコーディングcodex.wordpress.org/WordPress_Coding_Standards#Yoda_Conditions
トム・オージェ

13

これは、割り当て演算子の偶発的な使用を防ぐための防御的なコーディングメカニズムです。

等価演算子の代わりに代入演算子の誤用/エラーを考慮してください

if ( $options['postlink'] = 1  )

上記の条件は常にtrueを返しますが、それはおそらく元のプログラマーが念頭に置いていたものではありません。その場所で、これを考慮してください

if( 1 = $options['postlink'])

ここで、PHP(および他のほとんどの言語)は、の固定値に何かを割り当てることができないため、実行を拒否します1。この方法ですべての条件ステートメントをコーディングすることにより、条件で代入演算子を誤って使用しないように自動的に保証します。


9

nullポインタ例外の可能性を取り除くために、Javaでその規則を使用するのが好きです。そのため、このようなことで問題が発生したり、余分なコードが必要になったりすることはありません。

String foo = null;

if ("bar".equals(foo))
{
    //Do something
}

3
私はこれが好きですが、私は一般的なイディオムが嫌いです。
トーマスエディング

3
コード内のその時点までにヌル値が有効でない場合は、とにかくそれをチェックするか、ヌル値が不可能になるような方法でコードを設計する必要があります。
エドS.

6
これは問題をマスクする簡単な方法のようです。ほこりは、カーペットの内側でそれらをすくめてクリーニングされません。
ライライアン

0

実際には、多くのコンパイラは「if(x == 1)」ではなく「if(x = 1)」と書くと警告を出します。これは間違いである可能性が高いためです。

Clangを使用すると、コンパイラに「私はそれを意味し、自分がやっていることを知っている」と効果的に伝えることで警告を回避できます。これは「if((x = 1))」余分な括弧に注意してください。他の状況でも同様に機能します。if(false)ステートメント; ステートメントが実行されないという警告が表示される場合があります。if((false))ステートメント; その警告を与えません。


私はそれがとても好きです!私はいつも私のIDEに警告を得るため、PHPで以下、完全に合法的なイディオムをIを避ける:if ($array = getSomething()){ // ..so something with $array }
トム・オージェ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.