为什么switch语句中不包含break的case选项会在没有check的情况下自动转发到下一个case?
try {
switch($param) {
case "created":
if(!($value instanceof \DateTime))
throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
case "Creator":
if(!($value instanceof \Base\User)) {
throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");
}
default:
$this->$param = $value;
break;
}
} catch(Exception $e) {
echo $e->getMessage();
}
如果param是“创建的”,它将在创建的案例中进行检查,这很好。当检查成功时,我希望代码继续使用默认选项,这就是没有中断的原因;但相反,它继续“创造者”而$ param!=“创造者”!
我知道如何解决这个问题(只需在我的情况下“创建”添加默认代码),但我不喜欢经常重复该代码。我的实际问题是:为什么在案例不是“创作者”的情况下继续使用“创作者”案例。
答案 0 :(得分:19)
Fallthrough是一个有意的设计功能,允许使用以下代码:
switch ($command) {
case "exit":
case "quit":
quit();
break;
case "reset":
stop();
case "start":
start();
break;
}
它的设计使得执行在不同情况下运行。
default
就像其他任何情况一样,除非在没有其他情况被触发的情况下跳跃。它绝不是“在运行实际选择的案例之后执行此操作”指令。在您的示例中,您可以考虑:
switch($param) {
case "created":
if(!($value instanceof \DateTime))
throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
break;
case "Creator":
if(!($value instanceof \Base\User)) {
throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");
}
break;
}
$this->$param = $value;
这里的经验法则是,如果它不依赖于开关,则将其移出开关。
答案 1 :(得分:1)
因为它是如何完成的in C。
答案 2 :(得分:1)
也许这会启发你:
答案 3 :(得分:1)
我真的不知道你想要什么。
所有工具都在那里。
答案 4 :(得分:0)
回答你的“实际问题”:为什么在案件不是“创作者”的情况下继续使用“创作者”案例。
因为您没有break
。没有它,它将继续下面的情况。我能想到的唯一解决方案是将默认代码放到案例中,然后添加break
。
此外,您在默认情况下不需要break
,因为它是交换机块中的最后一种情况。
答案 5 :(得分:0)
在 PHP 8 中,我们有 match
,类似于 switch
表达式,但明显更短:
示例:
$message = match ($statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};
这是它的 switch
等价物:
switch ($statusCode) {
case 200:
case 300:
$message = null;
break;
case 400:
$message = 'not found';
break;
case 500:
$message = 'server error';
break;
default:
$message = 'unknown status code';
break;
}