2016-02-19 13 views
5

this blog postと読みましたが、 "3項演算子は左結合"の部分で混乱していました。そのため、インタープリターでサンプルコードを実行しました:ネストされた3項演算子phpとjavaのアソシエイティブ

$arg = 'T'; 
$vehicle = (($arg == 'B') ? 'bus' : 
      ($arg == 'A') ? 'airplane' : 
      ($arg == 'T') ? 'train' : 
      ($arg == 'C') ? 'car' : 
      ($arg == 'H') ? 'horse' : 
      'feet'); 
echo $vehicle; 

実際には、ブログ投稿のポイントであった反目直感であるhorseを返します。

好奇心をそらして、私は「左の連想」が望むと思うものに合わせて書き直して、「この作品を作ろう」としました。私は、この(フォーマットが奇妙であるが、それは私の頭の中で、少なくともそれがより明確になります)だ:今

$arg = 'T'; 
$vehicle = (($arg != 'B') ? 
       ($arg != 'A') ? 
        ($arg != 'T') ? 
         ($arg != 'C') ? 
          ($arg != 'H') ? 
           'feet' : 
          'horse' : 
         'car' : 
        'train' : 
       'airplane' : 
      'bus' 
); 
echo $vehicle; 

、このいままでの文字$argがあることは、その文字で始まる車両を返すという意味で期待どおりに動作します(もちろん小文字ですが、ここでは重要ではありません)。

奇妙なことに、前者がなぜ機能しないのか分からないので、後者が正しい連想語で失敗するかどうかは疑問だった。だから、私はそれをJavaインタプリタでテストしました。数秒で試して保存したいと思っている人のためのコードです。

class Main { 
    public static void main(String[] args) { 


    Character arg = 'a'; 
    String vehicle = ((arg == 'B') ? "bus" : 
         (arg == 'A') ? "airplane" : 
         (arg == 'T') ? "train" : 
         (arg == 'C') ? "car" : 
         (arg == 'H') ? "horse" : 
         "feet"); 
    System.out.println(vehicle); 
    vehicle = ((arg != 'B') ? 
        (arg != 'A') ? 
         (arg != 'T') ? 
          (arg != 'C') ? 
           (arg != 'H') ? 
           "feet" : 
          "horse" : 
         "car" : 
        "train" : 
       "airplane" : 
      "bus" 
    ); 
    System.out.println(vehicle); 
    } 
} 

どちらの形式もjavaで動作します。だから、PHPで何を与えるのですか?私は本質的に最終的な平等を最終的な平等として評価していると聞いています($arg == 'H')。しかしそうであれば、そのように振る舞うことを意味します。

$vehicle = ((($arg == 'B') || ($arg == 'A') || ($arg == 'T') || 
      ($arg == 'C') || ($arg == 'H')) ? 'horse' : 'feet'); 

これは私には意味がありません。私が与えた2番目のPHPの例では、if falseの部分ではなく、3進表現のif trueの部分に入れ子になっている部分だけを移動しました。私はなぜ第一の方法がうまくいかないのか分かりません。これは、「これはどうすればうまくいくのか」よりも、エラーに似ているように思えます。そして、私はちょうど誤解しているだけです。

注:私はちょうど(明らかに右結合である)私が望むように評価される式を強制的に物事の周りに括弧をラップすることができます知っています。私は「この作品を作る方法」を探しているわけではありません。なぜそうでないのかを知りたいのです。

答えて

2

右結合は、複数の演算子を組み合わせて使用​​する場合の優先順位です。 A + B + C。余分三オペレータが置き換えられたときに、これが唯一の意味を有する三オペレータA ? B : Cについて

C一部(又は A一部):余分三オペレータが中央に挿入されている場合

A ? B : X ? Y : Z 
(A ? B : X) ? Y : Z <-- left-associative (PHP) 
A ? B : (X ? Y : Z) <-- right-associative (Java, C, C++, C#, Perl) 

Bを置換)それはただ1つの意味を持つことができます:

A ? X ? Y : Z : C 
A ? (X ? Y : Z) : C 

これは、PHPとJavaが第2のものに同意する理由です。左/右結合ルールは適用されません。

+0

わかりました。 X 'は、' 0 'または 'false'のに評価されない何かではありません'、最終的な評価は、最初のケースで、その後Y.そうなので、 '$ argの==' B''は' false'を... '$ですarg == 'A''は 'false' ...' $ arg ==' T''は 'true' ...' train'は 'true'と評価されます...' car'は 'true'と評価されます。 ..最終的な価値は '馬'ですか? –

+0

@MiaoLiuあなたはそれを持っています。 ---結論:左連想三項演算子は非常に悪い設計です。または、[リンクされたブログ](http:// eev。ee/blog/2012/04/09/php-a-fractal-of-bad-design /):* PHPはデザインが悪い*。離れてください。 – Andreas

+0

これは、Javaでは、最も深くネストされた三項式が最初に評価され、その式の結果が外部式の戻り値の1つとして使用されることを意味します。次に、外部式が評価され、その戻り値が次の外部ステートメントなどに使用されます。 – Ungeheuer