Я достаточно способен использовать PHP-тернарный оператор. Однако я попал в блокпост при попытке выяснить, почему приведенный ниже код не соответствует эквивалентной структуре if-else. Тест проводился три раза по разным числам. Выход для каждой структуры ниже кода.
троичной:
$decimal_places = ($max <= 1) ? 2 : ($max > 3) ? 0 : 1;
Тройной выход:
max: -100000 decimal: 0
макс: 0.48 дробный: 0
max: 0,15 десятичных знаков: 0
Если еще
if($max <= 1) $decimal_places = 2; elseif($max > 3) $decimal_places = 0; else $decimal_places = 1;
If-Else Output:
max: -100000 десятичная: 2
макс: 0,48 десятичный: 2
макс: 0,15 дробный: 2
Может кто-нибудь, пожалуйста, скажите мне, почему эти две контрольные структуры не выводят одни и те же данные?
Ваше правостороннее тернарное выражение должно быть заключено в круглые скобки, поэтому оно будет оцениваться само по себе как одно выражение:
$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); // Another way of looking at it $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);
В противном случае ваше тернарное выражение оценивается слева направо, в результате чего:
$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; // Another way of looking at it $decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1;
Который, переведенный в if-else, становится следующим:
if ($max <= 1) $cond = 2; else $cond = ($max > 3); if ($cond) $decimal_places = 0; else $decimal_places = 1;
Поэтому $decimal_places
заканчивается как 0
для всех значений $max
за исключением 2
, и в этом случае он оценивается в 1
.
Код выполняется как
$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1;
поэтому вы никогда не получите 2 и 1 только при 1 < $max <=3
. Это связано с тем, что условный оператор лево-ассоциативный . Решение. Поместите скобки, чтобы убедиться, что нужный вам порядок закодирован:
$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);
Просто поставьте скобку, и все будет хорошо, вот так:
$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);
Как указывали другие, используйте paranthesis.
Однако, если вы действительно хотите сделать его доступным для чтения, то об этом:
$decimal_places = ($max <= 1) ? 2 : ( ($max > 3) ? 0 : ( 1 ));
Это все еще выглядит очень неудобно, но эта неловкость имеет правильную форму, поэтому с ней легче жить.
$drink = 'wine'; return ($drink === 'wine') ? 'vinyard' : ( ($drink === 'beer') ? 'brewery' : ( ($drink === 'juice') ? 'apple tree' : ( ($drink === 'coffee') ? 'coffeebeans' : ( 'other' ))));
Конечно, вы могли бы опустить последнюю пару скобок, но это сделало бы ее менее регулярной.