【问题标题】:nested php ternary trouble: ternary output != if - else [duplicate]嵌套的php三元问题:三元输出!= if - else [重复]
【发布时间】:2011-06-16 00:00:23
【问题描述】:

我很擅长使用 PHP 三元运算符。但是,我在试图弄清楚为什么下面的代码与 if-else 等效结构不匹配时遇到了障碍。测试在不同的数字上运行了 3 次。每个结构的输出都在代码下方。

三元:

$decimal_places = ($max <= 1) ? 2 : ($max > 3) ? 0 : 1;

三元输出:

最大值:-100000 十进制:0

最大值:0.48 十进制:0

最大值:0.15 十进制:0

如果-否则

if($max <= 1)
 $decimal_places = 2;
elseif($max > 3)
 $decimal_places = 0;
else
 $decimal_places = 1;

If-Else 输出:

最大值:-100000 十进制:2

最大值:0.48 十进制:2

最大值:0.15 十进制:2

谁能告诉我为什么这两个控制结构不输出相同的数据?

【问题讨论】:

  • 嵌套三元运算符不是一个好主意的一个原因
  • 它们不是完全等价的,你知道的。整个elseif会在三元结构中短路。它们也不意味着嵌套。
  • From the PHP Manual on Ternary Operators:建议避免“堆叠”三元表达式。在单个语句中使用多个三元运算符时 PHP 的行为并不明显
  • @Mark Ba​​ker 我只尝试将它们嵌套在非常简单的语句中,因为我见过三元语句让你想做一些暴力的事情。
  • 三元运算符的所有用法让我想做一些暴力的事情。添加它们的理由为零。人类阅读代码的次数远远超过编写代码的次数。正如您在问题中看到的那样,使用三元运算符等糟糕的构造使其“简洁”会增加错误并降低可维护性。

标签: php


【解决方案1】:

代码执行为

$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1;

所以只有当1 &lt; $max &lt;=3 时,你永远不会得到 2 和 1。这是因为条件运算符是left-associative。解决方案:用括号确保您想要的顺序是编码的:

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);

【讨论】:

    【解决方案2】:

    您的右侧三元表达式需要用括号括起来,以便它自己作为单个表达式进行评估:

    $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);
    
    // Another way of looking at it
    $decimal_places = ($max <= 1)
                    ? 2
                    : (($max > 3) ? 0 : 1);
    

    否则你的三元表达式从左到右求值,结果是:

    $decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1;
    
    // Another way of looking at it
    $decimal_places = (($max <= 1) ? 2 : ($max > 3))
                    ? 0
                    : 1;
    

    翻译成 if-else 后变成这样:

    if ($max <= 1)
        $cond = 2;
    else
        $cond = ($max > 3);
    
    if ($cond)
        $decimal_places = 0;
    else
        $decimal_places = 1;
    

    因此,对于 $max 的所有值,$decimal_places 最终都为 02 除外,在这种情况下,它的计算结果为 1

    【讨论】:

      【解决方案3】:

      只要加上括号就可以了,像这样:

       $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1);
      

      【讨论】:

        【解决方案4】:

        正如其他人指出的那样,使用括号。
        但是,如果你真的想让它可读,那又如何呢:

        $decimal_places =
          ($max <= 1) ? 2 : (
          ($max > 3)  ? 0 : (
          1
        ));
        

        这看起来还是超级别扭,不过这种别扭有规律,所以更容易相处。

        $drink = 'wine';
        return
          ($drink === 'wine')   ? 'vinyard' : (
          ($drink === 'beer')   ? 'brewery' : (
          ($drink === 'juice')  ? 'apple tree' : (
          ($drink === 'coffee') ? 'coffeebeans' : (
          'other'
        ))));
        

        您当然可以省略最后一对括号,但这会使其看起来不那么规则。

        【讨论】:

        • 确实超级尴尬,但我仍然觉得这对我来说很好(因为我有很多控制 if 语句内的开关等......)
        猜你喜欢
        • 1970-01-01
        • 2017-11-08
        • 1970-01-01
        • 2015-06-05
        • 1970-01-01
        • 2022-07-12
        • 1970-01-01
        • 2011-12-01
        • 2021-03-31
        相关资源
        最近更新 更多