PHP vs Java 中的嵌套三元运算符关联性


Nested Ternary-operator Associativity in php vs 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');

这对我来说没有意义。 在我给出的第二个 php 示例中,我只移动了等式所在的位置,嵌套在三元表达式的if true部分,而不是if false部分。 我不明白为什么如果第二种方法有效,第一种方法将不起作用。 这似乎更像是一个错误,而不是"这就是它应该的工作方式",我只是误解了事情,我必须这样做。

注意:我知道我可以在事物周围用括号括起来,以强制以我想要的方式计算表达式(这显然是右关联)。 我不是在寻找"如何使这项工作",我想知道为什么它没有。

左关联与右关联是关于将多个运算符串在一起时的优先级,例如 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),则只能具有一种含义:

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

这就是为什么PHP和Java在第二个问题上达成一致。没有应用左/右关联规则。