【问题标题】:default as first option in switch statement?默认作为switch语句中的第一个选项?
【发布时间】:2010-11-17 12:30:52
【问题描述】:

我已经对此进行了测试,它工作正常,但它看起来……很奇怪……对我来说。我是否应该担心这是非标准形式,将在 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)

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

【问题讨论】:

  • 还想提一下——我不是 PHP 菜鸟。我只是想获得其他 PHP 专业人士的意见
  • 我个人这样做是因为如果他们不选择任何内容,默认选项是表单中的第一个选项,因此按顺序阅读选项会更容易......默认为第一的。我刚来这个问题是为了确认它会起作用。
  • 在编程中,当我们发现需要以非常规方式解决问题时,最好在开关上方留下评论以解释您为什么要这样写你做到了。

标签: php syntax switch-statement


【解决方案1】:

这是一个不寻常的成语,当你阅读它时它会引起一点停顿,片刻的“嗯?”。它有效,但大多数人可能希望在最后找到默认情况:

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;

}

【讨论】:

  • 我同意,我在 10 多年的编程中编写的所有其他开关都是这样的。但是在这种 one 的情况下,如果我这样写,我需要两个 switch 语句。
  • 好的,我收回。我需要: case 'kind1': default: $kind='kind1';
  • 好的,对不起,我不知道我是怎么错过你的回答的。为了清楚起见,我可能会走那条路。
  • 在这么多人的第一反应和我一样之后,我决定这是要走的路。
  • 如果您希望默认为第一种情况,则将默认值放在首位很有用,并且您觉得将第一种情况放在首位而不是最后一个更有意义......例如当案件已编号。 DanielM 在下面回答了这个问题。它也是可读的。
【解决方案2】:

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

我想知道和乔希一样的事情 - 所以... 一件事是标准,我认为我们都应该更加努力地遵守它,但另一件事是黑客攻击(以:利用每一种可能性的方式)。

虽然它丑陋/奇怪/不正常 - 这是可能的,恕我直言,在极少数情况下可能会有用......

考虑以下几点:

$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】:

    出于同样的原因,它看起来很奇怪

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

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

    此外,您知道每次您将代码展示给某人,您将不得不解释将default 案例放在首位是故意的;这通常表明这不是一个好主意。

    【讨论】:

    • 我发誓我耸了耸肩。起初我不知道什么更奇怪,否则首先或 1==1...+1 只是让我去wtf?
    【解决方案4】:

    这就是我可能会这样做的方式......它既美观又保持功能。

    switch($kind)
    {
        default :
        case 'kind1': 
            $kind = "kind1";
            // Do stuff for kind 1 
            break;
    
        case 'kind2':
            // do stuff for kind2 
            break;
    
        case 'kindn':
            // do stuff for kindn 
            break;
    }
    

    【讨论】:

    • 首先我怀疑default: 是否让 PHP 忽略了声明的其余部分,但这个真的很管用!
    • 虽然您的示例更具可读性且不那么模棱两可,但我认为作者正在利用默认情况为 $kind 变量设置默认值,然后将下一个情况作为默认操作.如果代码依赖于该变量,这可能很有用。基本上,这使得case 'kind1': 成为无效数据的默认操作以及选项有效数据并同时减少代码冗余
    • @RisingSun 感谢您发现这个!这个答案至少错了 10 年。已更正。
    【解决方案5】:

    我个人更喜欢这样做

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

    【讨论】:

    • 谢谢,这就是我决定做的。我接受了保罗的回答,因为他是第一个。但是为你 +1 :-)
    • 是的,这种事一直发生在我身上——太糟糕了!对不起:-)
    【解决方案6】:

    这对于流控制非常方便,尤其是在您没有在不同情况之间中断的情况下。

    例如:

    $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',但这只是额外的代码,会降低可读性。

    【讨论】:

    • 这个,因为如果你想让默认值默认为第一种情况,把默认值放在第一位很有用,你觉得把第一种情况放在第一位而不是最后一个更有意义……比如当它们像这样编号时。
    【解决方案7】:

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

    【讨论】:

    • 非常感谢。作为我公司的首席开发人员,我可以设置优先级:-)(我想在选择我的道路之前获得其他人的意见的另一个原因)
    • 那么您应该将标准设置为默认值作为 switch 语句中的最后一个选项。对于大多数程序员来说,我看起来很“正常”。
    • 因为代码中的所有其他 switch 语句都是这样,我同意。谢谢!
    • 您不会尝试将其设置为优先级吧?这会让任何未来的开发者畏缩!
    • 为什么不呢?我以前从未见过 Josh 的布局 :) 几年前我做了很多 php *g
    【解决方案8】:

    一开始有点让我害怕,但那只是因为我们不习惯这样看事情。

    我建议您高度记录这一点,因为有些人可能会称之为“棘手”的代码。一个菜鸟或一些未来的维护者可能会出现并将它移到他们更舒服的底部,并打破顶部的副作用。

    【讨论】:

      【解决方案9】:

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

      除非您包含一个中断,否则一个案例(包括默认值)不会在其结束时停止执行。虽然 switch 经常被比作 if elseif elseif 等的序列,但事实并非如此。

      短版: SWITCH/CASE 只像 IF/ELSEIF/ELSE if 你在每个 case 之后都包含中断。 SWITCH/CASE 更像是一系列“if”语句,其中每个语句都有相同的变量检查,但检查的值不同。

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

      说真的,你为什么要这样做让我很吃惊,但它确实证明了 switch/case 与 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
      

      所以...您可以使用开关来回顾 BASIC 的时代... 但是如果你这样做了,我必须在你这样写完之后再调试你的代码...... 愿 Linus Torvalds 怜悯你的灵魂。

      【讨论】:

      • 我不明白为什么这被否决了。我只是想稍微澄清一下功能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 2020-10-18
      • 1970-01-01
      • 2015-03-06
      相关资源
      最近更新 更多