PHP开关语句默认情况

9

如果在switch语句中有一个匹配的case,那么默认情况会被评估吗?

例如:

switch ($x) {
  case ($x > 5): print "foo";
  case ($x%2 == 0): print "bar";
  default: print "nope";
}

当x等于50时,您将看到foobar,或者foobarnope

6
你尝试运行这段代码了吗? - GreenMatt
2
如果没有匹配的情况,将执行默认情况。 - Tony M
2
FYI case ($x > 5) 的计算结果为 case 1: 或者 case true: - Matt
2
没有 break,你的代码将尝试匹配所有条件。有了 break,它会在第一个匹配时停止。 - N.B.
我不希望它在第一个匹配处停止。 我希望它对所有匹配的情况执行代码。 - beth
2
没有代码中断,它将执行第一个匹配的 case 和之后的每个 case。 - Adam Jenkins
4个回答

9

是的,如果没有"break",那么所有与第一个匹配的case相对应的操作都将被执行。控制流将“穿过”所有后续的case,并执行每个后续case下的所有操作,直到遇到break;语句或到达switch语句的结尾。

在您的示例中,如果$x的值为50,则实际上会看到"nope"

请注意,switch实际上执行的是一个简单的等式测试,即在switch关键字后面的表达式和在case关键字后面的每个表达式之间进行比较。

您的示例很不寻常,因为只有当$x的值为0时才会显示"foo"。(实际上,当$x的值为0时,您将看到的是"foo bar nope"。)

case关键字后面的表达式被评估,这在您的示例中返回0(如果条件测试为false)或1(如果条件测试为true)。而正是这个值(0或1)与$x进行比较。


6

如果在switch语句中有一个匹配的case,那么默认的case会被执行吗?

大多数情况下不会执行,默认的case通常会有break语句。但是在你的情况下,它也会执行default

此外,请尽量避免编写单行代码(以提高可读性):

$x = 10;

switch (true) {
  case ($x > 5):
      print "foo";

  case ($x%2 == 0):
      print "bar";

  default:
      print "nope";
}

将打印出foobarnope。因此回答你的问题:是的:-)


打印 foobarnope。只要任何一个情况为真,所有后续情况(包括默认情况)直到遇到 break(或 switch 结束)都将运行。http://codepad.viper-7.com/sjHYeZ - Jonathan Kuhn

3
这不是开关的工作原理。
根据手册
“switch”语句类似于在同一表达式上使用一系列“if”语句。在许多情况下,您可能希望将相同的变量(或表达式)与许多不同的值进行比较,并根据它等于哪个值执行不同的代码片段。这正是“switch”语句的用途。
像这样的评估:
case ($x > 5):

简单来说就是

case true:

或者

case false:

根据 $x 的值进行判断,因为 ($x > 5) 是一个评估,而不是一个。开关比较参数的值,以查看它是否等同于任何一个case

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

以上代码中的比较等同于
if ($x == ($x > 5)) {
    echo "foo";
} elseif ($x == ($x < 5)) {
    echo "bar";
} else {
    echo "five";
}

$x == 50 时,它等同于

if ($x == true) {
    echo "foo";
} elseif ($x == false) {
    echo "bar";
} else {
    echo "five";
}

相当于
if (true) { // $x == true is the same as saying "$x is truthy"
    echo "foo";
} elseif (false) {
    echo "bar";
} else {
    echo "five";
}

但是,如果您按照switch语句的正常使用方式(将参数与具体值进行比较):

switch ($x) {
    case 50:
        echo "foo ";
    case 30:
        echo "bar ";
    default:
        echo "foo-bar";
}

如果$x == 50,则输出将为

foo bar foo-bar

由于在您的情况下没有使用break关键字。

如果您在每个情况结尾添加了break关键字,那么您只会执行该特定情况的代码。

switch ($x) {
    case 50:
        echo "foo ";
        break;
    case 30:
        echo "bar ";
        break;
    default:
        echo "foo-bar";
        break;
}

输出:

foo 

4
不,你没有。看看你写的内容。你说你不能像那样使用开关,并且你错了——你可以这样做,没有什么能阻止任何人这么做。发表一个半正确的答案是很糟糕的,有人会走进来读你写的东西,认为你是对的,但事实并非如此。 - N.B.
3
OP的switch语句是完全有效的。在case中进行评估是完全有效且非常理想的代码。您的答案只显示了该语句的一种用法。 - Buggabill
1
@Matt - 你试图解释的逻辑没有问题,问题在于你对switch语句的解释。switch语句的行为与if语句完全相同。您可以比较值以获取truefalseswitch只是一种方便的发明,使人们不必键入100个if / else组合并将代码嵌套到无法理解的地步。 - N.B.
2
@Matt,我不同意其中一句话。“上述代码的输出将始终为默认值,除非$x==1”。这是不正确的。例如,在比较$x==($x>5)中,会对$x进行隐式转换为布尔值,只要$x!=0就会评估为true。如果$x=0,那么该语句实际上将返回true,因为$x将为false,$x>5也为false,所以你得到了false==false。如果$x=1到5,则该语句返回false,因为任何非0数字都会转换为布尔值true。因此该语句变成了true==false。任何大于5的数字该语句都将返回true,即true == true - Jonathan Kuhn
显示剩余7条评论

2

如果您自己尝试一下会更容易理解。

不过,无论如何,在一个case语句中不使用break,则所有后续case语句都将被执行(包括default语句)。


确实有其他地方可以找到问题的答案,但是如果我们这样做,就没有人能够获得声望分数了;-) - beth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接