2012-08-10 107 views
0

我最近讨论了如何处理比较switch,并需要帮助解决它。开关评估

如果我写一个switch如:

switch ($x){ 
    case ($x > 5): 
     echo "foo"; 
     break; 
    case ($x < 5): 
     echo "bar"; 
     break; 
    default: 
     echo "five"; 
     break; 
} 

哪个if说法是它等同于? AB

// A 

if ($x > 5) { 
    echo "foo"; 
} elseif ($x < 5) { 
    echo "bar"; 
} else { 
    echo "five"; 
} 

// B 

if ($x == ($x > 5)) { 
    echo "foo"; 
} elseif ($x == ($x < 5)) { 
    echo "bar"; 
} else { 
    echo "five"; 
} 

回答

5

给大家,让我澄清:

它相当于到B

它不是“两个”,它不是它的一个,有时它是另一个,它总是B。要了解为什么有时您会看到结果表明它可能是A,那么您需要了解how type coercion works in PHP

如果您在falsey值传递给的switch“说法”,并使用表达case s表示导致一个布尔值,他们将只有当你的表达式计算结果为FALSE匹配。


switch基本上是一个巨大if/elseif树执行在case秒后到switch(表达式的左侧)的值和表达之间松散比较(==代替===)(右侧)。

can be proved很好地对你的代码的变化:

$x = 0; 

switch ($x) { 
    case $x > -1: // This is TRUE, but 0 == FALSE so this won't match 
    echo "case 1"; 
    case $x == -1: // This is FALSE, and 0 == FALSE so this will match 
    echo "case 2"; 
} 

如果我们将其转换成两个if/elseif树:

A

$x = 0; 

if ($x > -1) { 
    // It matches here 
    echo "case 1"; 
} else if ($x == -1) { 
    // and not here 
    echo "case 2"; 
} 

B

$x = 0; 

if ($x == ($x > -1)) { 
    // It doesn't match here 
    echo "case 1"; 
} else if ($x == ($x == -1)) { 
    // ..but here instead 
    echo "case 2"; 
} 
2

即切换的情况是相当于B

编辑:

如果我们采取例如即$ x等于0:

$ X> 5将评估为假(并且0也评估为假),所以第一个if将打印栏,但第二个将打印foo。 交换机将被转换为这样的事:

switch ($x){ 
    case false: 
     echo "foo"; 
     break; 
    case true: 
     echo "bar"; 
     break; 
    default: 
     echo "five"; 
     break; 
} 

,并且将打印FOO(与B)

编辑2:

我试了一下,这样给了我:

与$ X = 0 =>开关(富),如果A(巴),如果B(富)

与$ X = 5 => SWITC H(5)中,如果A(5个),如果B(5)

与$ X = 7 =>开关(富),如果A(富),如果B(富)

+0

我知道这是** **乙,但我需要更多的的解释比解决这个问题的方式更有效,文件中的某些“注释”表明它可能是** A **。 – Matt 2012-08-10 15:30:39

+1

我编辑了答案 – Oussama 2012-08-10 15:36:38

2

你的例子是相当于B

如果你想用比较到你的交换机(以及相当于一个),你可以这样写:

switch (true) { // Use true instead of $x 
    case ($x > 5): 
     echo "foo"; 
     break; 
    case ($x < 5): 
     echo "bar"; 
     break; 
    default: 
     echo "five"; 
     break; 
} 
+0

所以你说上面的代码等于* * A **? – Matt 2012-08-10 15:34:18

+0

是的,这就是我的意思。 – Florent 2012-08-10 15:35:17

0

我第一次发帖的时候是“答案是B”,但是SO没有接受它,因为“身体必须至少有30个字符;您输入15"

这里的证明,使用PHP 5.4.0:

<?php 

<?php 

function test($x) { 
    echo "Switch: "; 

    switch ($x){ 
     case ($x > 5): 
      echo "foo"; 
      break; 
     case ($x < 5): 
      echo "bar"; 
      break; 
     default: 
      echo "five"; 
      break; 
    } 

    echo "\nA: "; 

    if ($x > 5) { 
     echo "foo"; 
    } elseif ($x < 5) { 
     echo "bar"; 
    } else { 
     echo "five"; 
    } 

    echo "\nB: "; 

    // B 

    if ($x == ($x > 5)) { 
     echo "foo"; 
    } elseif ($x == ($x < 5)) { 
     echo "bar"; 
    } else { 
     echo "five"; 
    } 
} 

echo "Test with 6:\n\n"; 
test(6); 
echo "\n\nTest with 4:\n\n"; 
test(4); 
echo "\n\nTest with 5:\n\n"; 
test(5); 
echo "\n\nTest with true:\n\n"; 
test(true); 
echo "\n\nTest with false:\n\n"; 
test(false); 
echo "\n\n"; 

产生这样的输出:

 
    Test with 6: 

Switch: foo 
A: foo 
B: foo 

Test with 4: 

Switch: bar 
A: bar 
B: bar 

Test with 5: 

Switch: five 
A: five 
B: five 

Test with true: 

Switch: five 
A: five 
B: five 

Test with false: 

Switch: foo 
A: bar 
B: foo 
+0

怎么可能'$ x ==($ x> 5)'评估为'true'其中'$ x == 6'? – Matt 2012-08-10 15:39:32

+2

对不起,但这是不正确的。检查测试(0)以查看它的不同时间。原因是$ x ==($ x> 5)测试$ x == true是否为true,只要$ x不是0就可以评估为true ......现在我的评论似乎与您一样错位删除“他们是相同的”。 – MatsLindh 2012-08-10 15:41:45

+0

为了回答我自己的问题,@fiskfisk提出了一个很好的观点,即'$ x == true'计算为'true',因为'6'是'truthy'。 – Matt 2012-08-10 15:52:15