2012-08-10 72 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