Несколько условий в тройном операторе безопасно? - PullRequest
14 голосов
/ 02 сентября 2011

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

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

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

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

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

Спасибо!

Ответы [ 6 ]

24 голосов
/ 02 сентября 2011

Если результаты, которые вы возвращаете от троичного оператора, являются только «истиной» и «ложью», то вам даже не нужен оператор. Вы можете просто иметь:

$res = (($rule1 === true) && ($rule2 === false) && ($rule3 === true))

Но, чтобы ответить на ваш вопрос, да, несколько условий работают отлично.

5 голосов
/ 02 сентября 2011

Это абсолютно законно, работает и "так надежно, как если бы", но выглядит уродливо.

Если вы поместите каждое троичное выражение в круглые скобки, вложенность тоже подойдет:

$res = ( $rule1 ? true : ( $rule2 ? true : false ) )

Единственное, что не рекомендуется в руководстве, это вложение без круглых скобок, например:

$res = ( $rule1 ? true : $rule2 ? true : false )
4 голосов
/ 02 сентября 2011

Есть ли причина, по которой вы хотите сохранить ваши условия в переменной?это упрощенная версия выше.

if($rule1 && !$rule2 && $rule3)
{
    echo "good";
}
else
{
    echo "bad";
}
3 голосов
/ 02 сентября 2011

Вам не нужен троичный, если вы собираетесь вернуть true или false. Цитирование руководства:

Выражение (expr1) ? (expr2) : (expr3) оценивается как expr2, если expr1 оценивается как TRUE, и expr3, если expr1 оценивается как FALSE.

Это значит

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

уже присвоит true или false. Кроме того, если вас не волнует, что $ rule - логическое значение, вам не нужно сравнивать с ==. Вам также не нужны скобки, например,

$res = $rule1 && !$rule2 && $rule3;

совпадает с вашей начальной троичной.

Хорошая практика, когда у вас есть несколько таких выражений, это скрывать фактическое сравнение за значимым именем метода или функции, например,

function conditionsMet($rule1, $rule2, $rule3) {
    return $rule1 && !$rule2 && $rule3;
}

и тогда вы можете сделать

if (conditionsMet($rule1, $rule2, $rule3)) {
    // do something
}

Конечно, conditionsMet не , что значимо. Лучшим примером будет что-то вроде isSummerTime или isEligibleForDiscount и так далее. Просто укажите, что правила выражают в имени метода.

Вас также может заинтересовать Упрощение условных выражений из книги Рефакторинг - Улучшение дизайна существующего кода .

1 голос
/ 02 сентября 2011

Вы также можете сделать

 $res = ($rule1 && !$rule2 && $rule3);
0 голосов
/ 02 сентября 2011

Это законно и не должно быть "безобразным". Я часто использую оператор «крючка», в табличной форме он довольно чистый, например ::10000

bool haveANeed() 
{ 
    //     Condition       result
    //     ----------      ------
    return needToEat()   ? true
         : needToSleep() ? true
         : needToStudy() ? true
         : needToShop()  ? true
         : needToThink() ? true
         :                 false; // no needs!
}

Эта функция, ИМХО, будет менее понятной и, безусловно, более длинной, если будет написана с использованием логики if-else.

...