Подтвердить что ты не робот

Многочисленные условия в тройном операторе безопасны?

Я видел совет, в котором говорится, что тернарный оператор не должен быть вложенным.

Я тестировал код ниже, и он работает нормально. Мой вопрос: я не видел, как троичный оператор использовал это раньше. Таким образом, это так же надежно, как и в if, или может получиться что-то вроде этого и укусить меня позже (не в терминах или читаемости, а в случае неудачи).

$rule1 = true;
$rule2 = false;
$rule3 = true;

$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true)) ? true : false;

if($res) {
    echo "good";        
} else {
    echo "fail";
}

Спасибо!

4b9b3361

Ответ 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.