Многочисленные условия в тройном операторе безопасны?
Я видел совет, в котором говорится, что тернарный оператор не должен быть вложенным.
Я тестировал код ниже, и он работает нормально. Мой вопрос: я не видел, как троичный оператор использовал это раньше. Таким образом, это так же надежно, как и в if
, или может получиться что-то вроде этого и укусить меня позже (не в терминах или читаемости, а в случае неудачи).
$rule1 = true;
$rule2 = false;
$rule3 = true;
$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true)) ? true : false;
if($res) {
echo "good";
} else {
echo "fail";
}
Спасибо!
Ответы
Ответ 1
Если результаты, которые вы возвращаете из тернарного оператора, являются только "истинными" и "ложными", вам даже не нужен оператор. Вы можете просто:
$res = (($rule1 === true) && ($rule2 === false) && ($rule3 === true))
Но, чтобы ответить на ваш вопрос, да, несколько условий работают отлично.
Ответ 2
Есть ли причина, по которой вы хотите, чтобы ваши условия были сохранены в переменной? это упрощенная версия выше.
if($rule1 && !$rule2 && $rule3)
{
echo "good";
}
else
{
echo "bad";
}
Ответ 3
Это полностью законный, он работает и "настолько же надежный, как если бы", но выглядит уродливо.
Если вы помещаете каждое тернарное утверждение в скобки, вложение также будет прекрасным:
$res = ( $rule1 ? true : ( $rule2 ? true : false ) )
Единственное, что рекомендуется в руководстве, - это вложение без круглых скобок:
$res = ( $rule1 ? true : $rule2 ? true : false )
Ответ 4
Вам не нужен тройной, если вы собираетесь вернуть true
или false
. Цитата руководства:
Выражение (expr1) ? (expr2) : (expr3)
оценивается как expr2, если expr1 имеет значение TRUE, а expr3, если expr1 имеет значение FALSE.
Это означает
$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true));
уже назначит true или false. Кроме того, если не нужно, чтобы правило $было логическим, вам не нужно сравнивать с ==
. Вам также не нужны скобки, например.
$res = $rule1 && !$rule2 && $rule3;
совпадает с вашим начальным тройным.
Хорошая практика, когда у вас есть несколько выражений вроде этого, заключается в том, чтобы скрыть фактическое сравнение за значимым методом или именем функции, например.
function conditionsMet($rule1, $rule2, $rule3) {
return $rule1 && !$rule2 && $rule3;
}
а затем вы можете сделать
if (conditionsMet($rule1, $rule2, $rule3)) {
// do something
}
Конечно, conditionsMet
не имеет смысла. Лучшим примером может быть что-то вроде isSummerTime
или isEligibleForDiscount
и так далее. Просто скажите, что правила выражают в имени метода.
Вас также может заинтересовать Упрощение условных выражений из книги Рефакторинг - Улучшение дизайна существующего кода.
Ответ 5
Вы также можете сделать
$res = ($rule1 && !$rule2 && $rule3);
Ответ 6
Это законно и не обязательно быть "уродливым". Я часто использую оператор "hook", в виде таблицы он довольно чистый, например:
bool haveANeed()
{
// Condition result
// ---------- ------
return needToEat() ? true
: needToSleep() ? true
: needToStudy() ? true
: needToShop() ? true
: needToThink() ? true
: false; // no needs!
}
Эта функция будет, ИМХО, быть менее ясной и, конечно, дольше, если она написана с логикой if-else.