代码之家  ›  专栏  ›  技术社区  ›  Josh Andreas Rehm

默认为switch语句中的第一个选项?

  •  14
  • Josh Andreas Rehm  · 技术社区  · 15 年前

    我已经测试过了,效果很好,但看起来…奇怪的。。。对我来说。我应该关心的是,这是将在未来版本的PHP中删除的非标准表单,还是它可能会停止工作?我一直有一个默认案例作为最后一个案例,从来没有作为第一个案例……

    switch($kind)
    {
        default:
            // The kind wasn't valid, set it to the default
            $kind = 'kind1';
            // and fall through:
    
        case 'kind1':
            // Do some stuff for kind 1 here
            break;
    
        case 'kind2':
            // do some stuff for kind2 here
            break;
    
        // [...]
    
        case 'kindn':
            // do some stuff for kindn here
            break;
    
    }
    
    // some more stuff that uses $kind here...
    

    (如果不清楚我要做的是确保$kind是有效的,那么默认值是:case。但交换机也执行一些操作,然后在交换机之后也使用$kind。这就是违约的原因:陷入第一种情况,而且还设置了$kind)

    建议?这是正常/有效的语法吗?

    9 回复  |  直到 7 年前
        1
  •  21
  •   Jonathan Day    12 年前

    这是一个不寻常的成语,当你读它的时候,它会引起一点停顿,一瞬间“啊?”。它是有效的,但大多数人可能希望在结尾找到默认情况:

    switch($kind)
    {
        case 'kind2':
            // do some stuff for kind2 here
            break;
    
        // [...]
    
        case 'kindn':
            // do some stuff for kindn here
            break;
    
        case 'kind1':
        default: 
            // Assume kind1
            $kind = 'kind1';
    
            break;
    
    }
    
        2
  •  9
  •   Dan Larsen    13 年前

    如果有人像我一样通过谷歌找到这个页面:

    我和乔希一样想知道-所以… 一件事是标准,我认为我们都应该努力遵守,但另一件事是黑客攻击(在:以某种方式利用各种可能性)。

    虽然这很难看/奇怪/不正常-这是可能的,而且imho在一些罕见的情况下可能有用…

    考虑以下事项:

    $color = "greenish";
    //$color = "green";
    
    switch($color) {
        default:
            echo "no colors were selected so the color is: ";
        case "red":
            echo "red<br />\n";
            break;
        case "blue":
            echo "blue<br />\n";
            break;
        case "green":
            echo "green<br />\n";
            break;
    }
    

    如果 $color = "greenish"; 代码将打印

    未选择颜色,因此颜色为红色

    而如果 $color = "green"; 或任何其他已定义的情况下,它将只打印颜色。

    它知道这不是最好的例子,但你明白这一点;) 希望它能帮助别人。

        3
  •  4
  •   Frankie    14 年前

    这就是我可能会做的…它很容易被人看到并保持功能。

    switch($kind)
    {
        case 'kind1': default :
            // Do some stuff for kind 1 here
            break;
        case 'kind2':
            // do some stuff for kind2 here
            break;
        case 'kindn':
            // do some stuff for kindn here
            break;
    }
    
        4
  •  4
  •   Lightness Races in Orbit    13 年前

    看起来很奇怪,原因和

    else {
       echo "lol";
    }
    if (1 == 1) {
       echo "bbq";
    }
    

    如果它是有效的,看起来会很奇怪。如果仅仅因为这个原因,我会避免的。

    另外,你知道 每一次 你把代码给别人看,你得解释一下 default 案件首先是经过深思熟虑的;这通常表明这不是一个好主意。

        5
  •  3
  •   Mez    15 年前

    我个人更喜欢这样

    switch($kind)
    {
        case 'kind2':
            // do some stuff for kind2 here
            break;
    
        // [...]
    
        case 'kindn':
            // do some stuff for kindn here
            break;
    
        case 'kind1':
        default:
            $kind = 'kind1'; // Redundant if it's already set as 'kind1', but that doesn't make any difference to the code.
            // Do some stuff for kind 1 here
            break;
    
    }
    
        6
  •  2
  •   Henrik P. Hessel    15 年前

    通常的做法是将默认选项定义为最后一个选项。但是我认为您的解决方案没有任何问题(如果您的公司中没有预定义的模式,那么如何布局代码)

        7
  •  2
  •   Justin Johnson    15 年前

    一开始让我很痛苦,但那只是因为我们不习惯这样看待事情。

    我建议您高度记录这一点,因为有些人可能会称之为“棘手的”代码。一个noob或者一些未来的维护人员可能会来把它移动到底部,在那里他们更容易接受它,并打破了在顶部的副作用。

        8
  •  2
  •   DanielM Onshop    11 年前

    这对于流程控制非常方便,特别是在您不在案例之间中断的情况下。

    例如:

    $step = $_GET['skip_to_step'];
    switch($step) {
        default:
        case 'step1':
            // do some stuff for step one
        case 'step2':
            // this follows on from step 1 or you can skip straight to it
    }
    

    你可以加上一个“如果”,或者一个聪明的“或者”来 $step 默认为 'step1' 在启动开关之前,这只是额外的代码,降低了可读性。

        9
  •  1
  •   lilHar    7 年前

    其他答案给出了很好的例子,只是为了清楚起见…

    除非包含中断,否则案例(包括默认)不会在其结尾处停止执行。尽管开关经常被比作if-elseif-elseif等的序列,但它并不完全是这样。

    短版: 开关/外壳仅起到if/else if/else的作用 如果 每种情况下都包括休息时间。switch/case更像是一系列“if”语句,其中每个语句都有相同的变量检查,检查的值不同。

    长版本: 不包括休息,每个案例都是一个“开始在这里”,并且在很多方面的差异使得它更接近goto而没有缺点。从技术上讲,如果你真的想(读,是一个自虐的程序员,想真正挑战自己),你可以使用一个外部数组、一个for循环和一个嵌套在内部的开关来编写几乎所有的过程程序。

    说真的,你为什么要这样做让我很困惑,但它确实证明了开关/案例可以偏离if/elseif模式多远,所以出于学术原因(但不要这样做!)…

    $array = [];
    $array['masterLoop'] = 1;
    $for ($i = 0, $i < $array['masterLoop'], $i++ ){
        switch($array['goto']){
            default: 
            case 1: 
                PRINT: "Welcome to the program";
            case 2: 
                PRINT: "Please make a choice:";
            case 3:
                $array['choice']='';
                // Wait for some input variable and set choice to it.
            case 4: 
                $array['goto']=$array['choice'];
                $array['masterLoop']++;
        }
    }
    

    这段代码的运行方式(在设置了用于捕获和设置选项的内容之后)是

    "Welcome to the program. Please make a choice."
    <<user inputs 2>>
    "Please make a choice."
    <<user inputs 1>>
    "Welcome to the program. Please make a choice."
    <<user inputs 3>>
    // program awaits user input
    <<user inputs 4>>
    // user triggers infinite loop
    

    所以…您可以使用开关来反映基本的… 但是如果你这样做了,我必须在你这样写之后调试你的代码… 愿莱纳斯·托瓦尔兹宽恕你的灵魂。