Итак, я только что прочитал эту запись в блоге и меня смутила часть «тройной оператор является левой ассоциативной», поэтому я запустил пример кода в интерпретаторе:
$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
. Я не понимаю, почему первый метод не работает, если работает второй. Это больше похоже на ошибку, чем на «так должно работать», и я просто неправильно истолковываю вещи, как и должно быть.
ПРИМЕЧАНИЕ. Я знаю, что могу просто обернуть круглые скобки вокруг вещей, чтобы заставить выражение оцениваться так, как я хочу (что, по-видимому, является правоассоциативным). Я не ищу «как заставить это работать», я хочу знать, почему это не работает.