三元运算符中的多个条件是安全的


Multiple conditions in the ternary operator safe?

我看到建议说三元操作符不能嵌套。

我已经测试了下面的代码,它工作正常。我的问题是,我以前没见过这样使用三元运算符。所以,这是否像在if中使用的那样可靠,或者类似的东西以后会来咬我(不是在可读性方面,而是失败)。

$rule1 = true;
$rule2 = false;
$rule3 = true;
$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true)) ? true : false;
if($res) {
    echo "good";        
} else {
    echo "fail";
}

谢谢!

如果您从三元操作符返回的结果只有"真"answers"假",那么您甚至不需要操作符。你可以输入:

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

但是,回答你的问题,是的,多个条件都可以很好地工作。

这是完全合法的,它可以工作并且"像if一样可靠",但是它看起来很丑。

如果你把每个三元语句放在括号内,嵌套也会很好:

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

手册中唯一不建议的是不带括号的嵌套,像这样:

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

您想将条件保存到变量中是有原因的吗?这是上面的简化版本。

if($rule1 && !$rule2 && $rule3)
{
    echo "good";
}
else
{
    echo "bad";
}

如果您要返回truefalse,则不需要三元制。引用手册:

表达式(expr1) ? (expr2) : (expr3)如果expr1的值为TRUE则为expr2,如果expr1的值为FALSE则为expr3。

这意味着

$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不是有意义。一个更好的例子是isSummerTimeisEligibleForDiscount等等。只需在方法名中表达规则所表达的内容。

您可能还对《重构—改进现有代码的设计》一书中的简化条件表达式感兴趣。

你也可以做

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

这是合法的,不需要"丑陋"。我经常使用"hook"操作符,在表格形式中它非常干净,例如:

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

如果用if-else逻辑来写,这个函数会不那么清晰,而且肯定会更长。