Switch evaluations

谁说我不能喝 提交于 2020-01-17 05:34:05

问题


I recently got into an argument over how switch handles comparisons, and need help settling it.

If I write a switch such as:

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

Which if statement is it equivalent to? A or B?

// 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";
}

回答1:


To everyone, let me clarify:

It is equivalent to B.

It is not "both", it is not sometimes its one, sometimes it is the other, it is always B. To understand why you sometimes see results that indicate that it might be A, you need to understand how type coercion works in PHP.

If you pass in a falsey value to the "argument" of switch and you use expressions in your cases that result in a boolean value, they will only match if your expression evaluates to FALSE.


switch is basically a huge if/elseif tree that performs loose comparisons (== instead of ===) between the value passed to switch (the left side of the expression) and the expression in the cases (the right side).

This can be proved quite nicely with a variation on your code:

$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";
}

And if we convert that to the two if/elseif trees:

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:


Your example is equivalent to B.

If you want to use comparison into your switch (and be equivalent to A), you could write this:

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



回答3:


That switch case is equivalent to B

Edit :

If we take for example that $x is equal to 0 :

$x > 5 will evaluate to false (and 0 evaluates to false too), so the first if will print bar, but the second one will print foo. The switch will be transformed to something like this :

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

and that will print foo (same as B)

Edit 2 :

I tried it so that gave me :

with $x = 0 => switch (foo), if A (bar), if B (foo)

with $x = 5 => switch (five), if A (five), if B (five)

with $x = 7 => switch (foo), if A (foo), if B (foo)



来源:https://stackoverflow.com/questions/11904754/switch-evaluations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!