【问题标题】:Nested ternary statements [duplicate]嵌套三元语句[重复]
【发布时间】:2011-12-01 00:07:18
【问题描述】:

我想知道为什么这很奇怪。我知道区别在于分组,但比较起来重要吗?

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
   $i++;
}

返回

last_row
none
none
last_row

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : (($i == sizeof($feedbacks)-2) ? 'last_row' : 'none');
   $i++;
}

正确返回

first_row
none
none
last_row

为什么会有差异?

【问题讨论】:

    标签: php if-statement ternary-operator


    【解决方案1】:

    要使用基于您的代码的解释,缩小版本将是:

    for ($i=0; $i<5; $i++) {
       echo $i == 0 ? 'first_row' : $i == 4 ? 'last_row' : 'none';
    }
    

    在PHP中,这相当于写:

    for ($i=0; $i<5; $i++) {
       echo ($i == 0 ? 'first_row' : $i == 4) ? 'last_row' : 'none';
    }
    

    在第一次运行时,$i 的值为 0,因此第一个三元组返回 'first_row',并且该字符串用作第二个三元组的条件——在布尔上下文中计算为 true -- 因此'last_row' 被返回。

    如果你重新组合它:

    for ($i=0; $i<5; $i++) {
       echo $i == 0 ? 'first_row' : ($i == 4 ? 'last_row' : 'none');
    }
    

    那么第一个三进制的结果不会干扰第二个三进制。

    【讨论】:

      【解决方案2】:

      来自official PHP documentation

      “建议您避免“堆叠”三元表达式。PHP 在单个语句中使用多个三元运算符时的行为并不明显”

      显然,尽管 PHP 的三元运算符(以及它的大部分语法)基于 C,但出于某种原因,PHP 决定使用make it left-associative,而在 C 和基于它的大多数其他语言中,the ternary operator is right-associative

      C:

      $ cat /tmp/foo.c
      #include <stdio.h>
      void main (void) { printf("%s\n", ( 1 ? "foo" : 0 ? "bar" : "baz" ) ); }
      
      $ gcc -o /tmp/foo /tmp/foo.c; /tmp/foo
      foo
      

      Perl:

      $ perl -e 'print ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
      foo
      

      Java:

      $ cat /tmp/foo.java
      public class foo { public static void main(String[] args) {
          System.out.println( ( true ? "foo" : false ? "bar" : "baz" ) );
      } }
      
      $ javac -d /tmp /tmp/foo.java; java -cp /tmp foo
      foo
      

      JavaScript:

      $ cat /tmp/foo.js
      print( 1 ? "foo" : 0 ? "bar" : "baz" );
      
      $ rhino -f /tmp/foo.js
      foo
      

      PHP:

      $ php -r 'echo ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
      bar
      

      所以,是的,我认为我们可以有把握地得出结论,PHP 在(也)这方面是完全落后的。

      【讨论】:

      • 在支持其他语言的好例子和反对无视 php 之间有所缓解:/
      【解决方案3】:

      看看 JRL 提供的答案。为了更清楚地了解您的示例发生了什么,您应该了解您的表达式是这样评估的:

      echo (($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2)) ? 'last_row' : 'none';
      

      所以当$i == 0 你的陈述基本上变成这样:

      echo 'first_row' ? 'last_row' : 'none';
      

      由于'first_row' 的计算结果为true,因此您的'last_row'$i == 0 时返回的结果。当$i 不等于零时,您的声明基本上变成了这样:

      echo ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
      

      【讨论】:

        【解决方案4】:

        example 3 on php.net:

        <?php
        // on first glance, the following appears to output 'true'
        echo (true?'true':false?'t':'f');
        
        // however, the actual output of the above is 't'
        // this is because ternary expressions are evaluated from left to right
        
        // the following is a more obvious version of the same code as above
        echo ((true ? 'true' : false) ? 't' : 'f');
        
        // here, you can see that the first expression is evaluated to 'true', which
        // in turn evaluates to (bool)true, thus returning the true branch of the
        // second ternary expression.
        ?>
        

        重要的部分是:

        这是因为三元表达式是从左到右计算的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-08
          • 2013-05-17
          • 2012-02-02
          • 2021-07-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多