Тернарые ? операторы : perl ? python : ruby ? php : wtf?; Код (Text): shock@shock:~$ perl -e "print 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9" 2 shock@shock:~$ python -c "print 2 if 1 else 4 if 3 else 6 if 5 else 8 if 7 else 9" 2 shock@shock:~$ ruby -e "print 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9" 2 shock@shock:~$ php -r "echo 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9;" 8 shock@shock:~$ WTF ? bash: WTF?: команда не найдена PS. Java, C++ тоже вернули бы 2.
В чем причина? Возможно, оно работает так: PHP: 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9 => (((1 ? 2 : 3) ? 4 : 5) ? 6 : 7) ? 8 : 9 => true ? 8 : 9 => 8 Другие языки: Мое предположение: 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9 => 1 ? 2 : (3 ? 4 : 5 ? 6 : 7 ? 8 : 9) => 2 Предположение Xenius'a (наверное, более верное) 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9 => 1 ? 2 : 3 ? 4 : 5 ? 6 : (7 ? 8 : 9 == 8) => 1 ? 2 : 3 ? 4 : (5 ? 6 : 8 == 6 ) => 1 ? 2 : (3 ? 4 : 6 == 4) => 1 ? 2 : 4 => 2
Зачем это чудо надо? PHP: <? $var = empty($a) ? 'а должно быть числом' : empty($b) ? 'б должно быть числом' : ($a < $b) ? 'а - больше' : ($a > $b) ? 'б - больше' : 'Они равны'; Пример, конечно, очень надуманный, но это очень помогает быстро, легко и красиво задать разные значения переменной зависимо от условий и дефолтное значение, если все условия не соблюдены. другой пример: PHP: <? // С помощью тернарного оператора public function getSomething ($type = null) { return ($type === self::TYPE1) ? 'first value' : ($type === self::TYPE2) ? 'second value' : ($type === self::TYPE3) ? 'third value' : 'default value'; } // С помощью if-else public function getSomething ($type = null) { if ($type === self::TYPE1) { return 'first value'; } else if ($type === self::TYPE2) { return 'second value'; } else if ($type === self::TYPE3) { return 'third value'; } else { return 'default value'; } } // С помощью case-switch public function getSomething ($type = null) { switch ($type) { case self::TYPE1 : return 'first value'; break; case self::TYPE2 : return 'second value'; break; case self::TYPE3 : return 'third value'; break; default : return 'default value'; } }
Задам вопрос на засыпку: а зачем оно надо? Прошу дать адекватный обоснованный ответ, после которого я бы смог высказаться положительно об этой неудобночитаемой конструкции. Такой стиль написания кода называется неуважением к своему и чужому времени и совершенно бесполезен. Почему альтернативные управляющие инструкции менее распространены: PHP: <? if($a > $b): echo 'Yeah'; endif; ?> Да потому что при наличии более удобной альтернативы - фигурных группирующих скобок - эти конструкции отходят на второй план, а тернарный оператор вообще стилистически имеет ограниченное применение: только для проверки кратких условий, когда его использование ОБОСНОВАННО и приводит к более красивой группировке, нежели безосновательное использование if (пример я уже давал в другой теме).
Apple, добавил второй пример в третьем посте. Согласен. Чаще намного лучше использовать стандартный иф-элс, или свитч. Но изредка бывает более удобно и красиво использовать тернарный оператор.
Но все-равно. Крайне обидно, что вполне распространенный, удобный и используемый оператор имеет такую недоработку в пыхе. с Си ведь старались скопировать, наверное, а получилось совершенно иначе чем во всех остальных языках
К примеру выше добавлю свой пример: PHP: <? class ABC { const TYPE_1 = "int"; const TYPE_2 = "string"; const TYPE_3 = "double"; protected $types = array(); public function __construct() { $types = array(TYPE_1, TYPE_2, TYPE_3); } public function getSomething($type = null) { if(($type = array_search($type, $this->types)) !== false) return $this->types[$type]; return false; } } ?> В результате имеем: PHP: <?php public function getSomething($type = null) { if(($type = array_search($type, $this->types)) !== false) return $this->types[$type]; return false; } ?> это по теме надуманности. Никаких if-else или switch-case.
я думаю, его вполне можно сократить до PHP: <? public function getSomething($type = null) { return array_search($type, $this->types)) } и я думал, что к константам класса можно обращатся только через "селф::ИМЯ_КОНСТАНТЫ" А по поводу примера. Код с тернарным оператором, я подозреваю, быстрее. Тем более, способом с array_search нельзя будет сделать чтото типа: PHP: <? public function getSomething ($type = null) { return ($type === self::TYPE1) ? $this->method() : ($type === self::TYPE2) ? $this->prop : ($type === self::TYPE3) ? self::CONST1 : 'default value'; }
Тернарные операторы удобно проверять при более маленьких кодах, ибо если идёт куча проверок, то действительно можно запутаться с тернарным оператором А при проверках на истину/ложь, проверках значения в переменных можно и нужно использовать тернарный оператор. Это только моё мнение и всё
тем более в способе с константами-строками легче не вызывать метод, а обращатся сразу к константам: PHP: <?php echo ABC::TYPE_1; // Вместо $abc = new ABC; echo $abc->getSomething(ABC::TYPE_1); Потому данный пример делает совершенно иное, чем любой из методов getSomething в третьем посте.
Простите, ООП не учил( немного пробовал и получалось ), ибо не понимаю зачем оно нужно мне на данный момент. Пока буду просто следить за темой По мне уже как-то пофиг как читать маленький код, мнение отписал своё выше
что за проблемы? PHP: <? $var=empty($a)?"a empty":(empty($b)?"b empty":($a<$b?"a < b":($a!==$b?"a > b ":"a = b"))); ?>
Создай выражение с тернарными операторами, которое компьютер будет выполнять сутки и ты прославишься на весь мир как дол///
Кстати да, по идее, ? и : имеют равный приоритет и левую ассоциативность, поэтому должны разобратся в 2. Но, увы ) Хотя, в пхп есть баги и пострашней.