Необычная тройная операция
Мне было предложено выполнить эту операцию использования тройного оператора:
$test='one';
echo $test == 'one' ? 'one' : $test == 'two' ? 'two' : 'three';
Что печатает два (проверено с использованием php).
Я до сих пор не уверен в логике этого. Пожалуйста, может кто-нибудь сказать мне логику для этого.
Ответы
Ответ 1
Ну, а? и: имеют одинаковый приоритет, поэтому PHP будет анализировать слева направо, оценивая каждый бит по очереди:
echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three';
Первый $test == 'one'
возвращает true, поэтому первые parens имеют значение "one". Теперь второй тернар оценивается следующим образом:
'one' /*returned by first ternary*/ ? 'two' : 'three'
'one' истинно (непустая строка), поэтому 'two' является конечным результатом.
Ответ 2
В основном интерпретатор оценивает это выражение слева направо, поэтому:
echo $test == 'one' ? 'one' : $test == 'two' ? 'two' : 'three';
интерпретируется как
echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three';
И выражение в паратезах оценивается как true, так как "одно" и "два" не являются нулевыми/о/другими формами false.
Поэтому, если бы это выглядело так:
echo $test == 'one' ? FALSE : $test == 'two' ? 'two' : 'three';
Он напечатает три. Чтобы он работал нормально, вы должны забыть о объединении тернарных операторов и использовать обычный ifs/switch для более сложной логики или, по крайней мере, использовать скобки, чтобы интерпретатор понял вашу логику и не выполнял проверку стандартным способом LTR:
echo $test == 'one' ? 'one' : ($test == 'two' ? 'two' : ($test == 'three' ? 'three' : 'four'));
//etc... It not the most understandable code...
//You better use:
if($test == 'one')
echo 'one';
else { //or elseif()
...
}
//Or:
switch($test) {
case 'one':
echo 'one';
break;
case 'two':
echo 'two';
break;
//and so on...
}
Ответ 3
Он работает правильно, когда вы используете скобки:
<?
$test='one';
echo $test == 'one' ? 'one' : ($test == 'two' ? 'two' : 'three');
Я не понимаю его на 100%, но без скобок, для интерпретатора утверждение должно выглядеть так:
echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three';
результат первого условия, как представляется, возвращается в результате всей тройной операции.
Ответ 4
PHP документация говорит:
Примечание. Рекомендуется избегать "стекирования" трехмерных выражений. Поведение PHP при использовании нескольких тернарных операторов в одном выражении неочевидно:
Пример # 3 Неочевидное тернарное поведение
<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');
// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right
// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');
// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>
Если вы помещаете скобки вокруг ложного оператора, он печатает one
:
echo $test == 'one' ? 'one' : ($test == 'two' ? 'two' : 'three');
Ответ 5
Я думаю, что он оценивается следующим образом:
echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three';
($ test == 'one'? 'one': $test == 'two') не равен нулю /null, поэтому 'two' является логическим выходом
если вы хотите, чтобы он работал правильно, напишите:
echo $test == 'one' ? 'one' : ($test == 'two' ? 'two' : 'three');
Ответ 6
Тернарные операторы выполняются в порядке появления, поэтому у вас действительно есть:
echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three';
Ответ 7
Вложенные троичные операции являются грубыми! Вышеприведенное объяснение показывает, почему.
В основном это логика:
is $test == 'one'
if TRUE then echo 'one'
else is $test == 'two'
if TRUE then echo 'two'
else echo three