有没有更优雅的方法来执行此switch语句?

时间:2018-06-22 11:37:31

标签: php switch-statement

我的代码中有一个很大的switch语句,我希望它执行以下操作:

// assign $foo
switch ($foo) {
    case 1:
    case 2:
        // do X, then break if 1, do Y and break if 2
    case 3:
    case 4:
    case 5:
       // do A & B, break if 3, do C if 4 or 5, do D if 5 and then break
}

这种“组”在switch语句中很普遍,目前我只是重复逻辑,将每种情况分开。 我以为可以将其重组为客观上“更好”的东西是错误的吗?

编辑:我从问题中排除了我的原始代码段,因为它的逻辑存在严重缺陷,并且不符合使用switch(用伪代码替换)的基本概念类似于预期的结果。

2 个答案:

答案 0 :(得分:2)

如前所述,switch实际上并没有按照您的想法工作。

您只是在寻找:

if (in_array($foo, [1, 2])) {
    ...

    if ($foo == 2) {
        ...
    }
}

或者:

switch ($foo) {
    case 1:
    case 2:
        ...

        if ($foo == 2) {
            ...
        }
        break;
}

答案 1 :(得分:0)

TLDR ;
对于简单的“就是这样”,请使用开关,如果需要逻辑检查,请使用if

答案;
您要问的是相当主观的,而使用简单的开关就可以了,即

<?php
$case = getCaseFrom("X"); // Let's say this = "a"

switch ($case)
{
    case "a" : {
        $thing = "a";
        break;
    }
    case "b" : {
        $thing = "b";
        break;
    }
    case "c" : {
        $thing = "c";
        break;
    }
    default : {
        $thing = "d";
    }
}
?>

使用可以实现相同的效果

<?php
$case = getCaseFrom("x");
$thing = $case;
// And even shorter;
$thing = getCaseFrom("x");
?>

如果您对此需要一些逻辑...

<?php
$operator = getOperatorFrom("X"); // In this case, add
$num1 = 10;
$num2 = 2;

switch ($operator)
{
    case "add" : {
        $res = num1 + num2;
        break;
    }
    case "subtract" : {
        $res = num1 - num2;
        break;
    }
    case "multiply" : {
        $res = num1 * num2;
        break;
    }
    case "divide" : {
        $res = num1 / num2;
        break;
    }
}
?>

替代方案;
当然,上述所有开关情况都是使用if else子句完成的,但是开关(IMO)更加整洁,并且更易读,具体取决于您的特定条件(请参见缺点)。

最简单的查看方法是;

  

如果您需要检查某个值是否与某个值匹配,请使用if,如果它是一组枚举值(例如1到4),则从主观上讲,切换会更好

缺点;
例如,一个开关也不允许您在同一条语句中进行多个“和”检查;

<?php

$case = getCaseFrom("X"); // In this case, a (does not have "b")
switch ($case)
{
    case "a" :
    case "b" : {
        // This checks for a or b, not both, despite this not containing "b"
        // this will still be accessed
        break;
    }
    case "c" : {
        // This will not be used as the break stops
        // it from falling through to this clause
        break;
    }
}

if (stristr("a", $case) && stristr("b", $case)) 
{
    // This checks to see if case contains a AND b
    // therefore, this will not be used, as this 
    // does not have both a and b in $case
}
else if (stristr("a", $case) || stristr("b", $case)) 
{
    // This checks to see if case contains a OR b
    // therefore, this will be used, as this 
    // is checking that $case has "a" or "b" in it
    // This is the same as the switch in this instance as it uses "or"
}

值得关注;
注意以下内容也很有用;

例如,在交换机case中,您不能使用登录名;

case getThing("a") :

会导致错误

NB :当然,当使用case语句时,不需要添加花括号,它们主要用于代码折叠和易于阅读