php 与 java 中的嵌套三元运算符关联性
Nested Ternary-operator Associativity in php vs java
所以,我刚刚阅读了 this blog post,我对 "ternary-operator is left-associative" 部分感到困惑,所以我 运行 解释器中的示例代码:
$arg = 'T';
$vehicle = ( ( $arg == 'B' ) ? 'bus' :
( $arg == 'A' ) ? 'airplane' :
( $arg == 'T' ) ? 'train' :
( $arg == 'C' ) ? 'car' :
( $arg == 'H' ) ? 'horse' :
'feet' );
echo $vehicle;
事实上,它 returns horse
博客中的重点是违反直觉的 post。
出于好奇,我随后尝试 "make this work" 重写它以适应我认为 "left-associative" 想要的内容。我明白了(格式很奇怪,但至少在我的脑海中它使它更清晰):
$arg = 'T';
$vehicle = ( ( $arg != 'B' ) ?
( $arg != 'A' ) ?
( $arg != 'T' ) ?
( $arg != 'C' ) ?
( $arg != 'H' ) ?
'feet' :
'horse' :
'car' :
'train' :
'airplane' :
'bus'
);
echo $vehicle;
现在,这按预期工作,因为任何字符 $arg
都是 returns 以该字符开头的车辆(当然是小写,但这在这里并不重要)。
仍然很好奇,因为我不清楚为什么前者不起作用,我想知道后者是否会在右联想语言中失败,因为它似乎不会。所以我在 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
部分。我不明白为什么第一种方法在第二种方法行得通的情况下行不通。这看起来更像是一个错误而不是 "this is how it should work",我只是误解了事情,我一定是这样。
注意:我知道我可以将括号括起来以强制表达式以我想要的方式求值(这显然是右结合的)。我不是在找"how to make this work",我想知道为什么没有。
左结合与右结合是关于将多个运算符串在一起时的优先级,例如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 同意第二个。没有应用 left-/right-associative 规则。
所以,我刚刚阅读了 this blog post,我对 "ternary-operator is left-associative" 部分感到困惑,所以我 运行 解释器中的示例代码:
$arg = 'T';
$vehicle = ( ( $arg == 'B' ) ? 'bus' :
( $arg == 'A' ) ? 'airplane' :
( $arg == 'T' ) ? 'train' :
( $arg == 'C' ) ? 'car' :
( $arg == 'H' ) ? 'horse' :
'feet' );
echo $vehicle;
事实上,它 returns horse
博客中的重点是违反直觉的 post。
出于好奇,我随后尝试 "make this work" 重写它以适应我认为 "left-associative" 想要的内容。我明白了(格式很奇怪,但至少在我的脑海中它使它更清晰):
$arg = 'T';
$vehicle = ( ( $arg != 'B' ) ?
( $arg != 'A' ) ?
( $arg != 'T' ) ?
( $arg != 'C' ) ?
( $arg != 'H' ) ?
'feet' :
'horse' :
'car' :
'train' :
'airplane' :
'bus'
);
echo $vehicle;
现在,这按预期工作,因为任何字符 $arg
都是 returns 以该字符开头的车辆(当然是小写,但这在这里并不重要)。
仍然很好奇,因为我不清楚为什么前者不起作用,我想知道后者是否会在右联想语言中失败,因为它似乎不会。所以我在 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
部分。我不明白为什么第一种方法在第二种方法行得通的情况下行不通。这看起来更像是一个错误而不是 "this is how it should work",我只是误解了事情,我一定是这样。
注意:我知道我可以将括号括起来以强制表达式以我想要的方式求值(这显然是右结合的)。我不是在找"how to make this work",我想知道为什么没有。
左结合与右结合是关于将多个运算符串在一起时的优先级,例如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 同意第二个。没有应用 left-/right-associative 规则。