Coding style Switch语句失败…是否允许?

Coding style Switch语句失败…是否允许?,coding-style,switch-statement,Coding Style,Switch Statement,在我记忆中,我一直避免使用switch语句fall-through。事实上,我不记得它曾经作为一种可能的做事方式进入我的意识,因为它在我的头脑中很早就被灌输了,它只不过是switch语句中的一个bug。然而,今天我遇到了一些代码,这些代码是通过设计来使用它的,这让我立即想知道社区中的每个人对switch语句失败的看法 这是编程语言不应该明确允许的(像C#一样,尽管它提供了一个解决方法),还是任何强大到足以让程序员掌握的语言的一个特性 编辑: 我对我所说的失败的意思不够明确。我经常使用这种类型:

在我记忆中,我一直避免使用switch语句fall-through。事实上,我不记得它曾经作为一种可能的做事方式进入我的意识,因为它在我的头脑中很早就被灌输了,它只不过是switch语句中的一个bug。然而,今天我遇到了一些代码,这些代码是通过设计来使用它的,这让我立即想知道社区中的每个人对switch语句失败的看法

这是编程语言不应该明确允许的(像C#一样,尽管它提供了一个解决方法),还是任何强大到足以让程序员掌握的语言的一个特性

编辑: 我对我所说的失败的意思不够明确。我经常使用这种类型:

开关(m_loadAnimt){
案例0:
案例1:
//做点什么
打破
案例2:
案例3:
案例4:
//做点什么
打破
}
然而,我担心这样的事情

开关(m_loadAnimt){
案例0:
案例1:
//做点什么,但要解决其他问题
//做完之后。
案例2:
案例3:
案例4:
//做点别的。
打破
}

这样,每当case为0,1时,它将执行switch语句中的所有操作。我已经看到了这一点,我只是不知道我是否同意switch语句应该这样使用。我认为第一个代码示例非常有用和安全。第二种似乎有点危险。

失败确实是一件方便的事情,这取决于你在做什么。考虑这样一种简洁易懂的安排方式:

switch ($someoption) {
  case 'a':
  case 'b':
  case 'c':
    // Do something
    break;

  case 'd':
  case 'e':
    // Do something else
    break;
}

想象一下用if/else这样做。这将是一片混乱。

它强大而危险。fall-through的最大问题是它不明确。例如,如果您遇到频繁编辑的代码,其中有一个带有下拉开关的开关,您如何知道这是故意的而不是错误

无论我在哪里使用它,我都会确保它得到了正确的评论:

switch($var) {
    case 'first':
        // Fall-through
    case 'second':
        i++;
        break;
 }
你听说过吗?这是使用switch fallthrough的一个很好的例子


与几乎所有语言功能一样,这是一种可以使用也可以滥用的功能。

在某些情况下,使用下拉列表是程序员的一种懒惰行为-例如,他们可以使用一系列的| |语句,但可以使用一系列的“一网打尽”切换情况

尽管如此,我发现它们特别有用,因为我知道最终我还是需要这些选项(例如在菜单响应中),但还没有实现所有选项。类似地,如果您同时对“a”和“a”进行遍历,我发现使用开关遍历比使用复合if语句要干净得多


这可能是风格和程序员的想法的问题,但我通常不喜欢以“安全”的名义删除语言的组件——这就是为什么我更倾向于C及其变体/后代,而不是Java。我喜欢在没有“理由”的情况下用指针之类的东西胡闹。

与任何东西一样:如果小心使用,它可能是一个优雅的工具

然而,我认为缺点不仅仅是不使用它的理由,最后是不允许再使用它(C#)。这些问题包括:

  • 很容易“忘记”休息
  • 对于代码维护人员来说,忽略中断是故意的,这并不总是显而易见的
开关/外壳的良好使用故障:

switch (x)
{
case 1:
case 2:
case 3:
 Do something
 break;
}
switch (x)
{
case 1:
    Some code
case 2:
    Some more code
case 3:
    Even more code
    break;
}
BAAAAD开关/外壳的使用故障:

switch (x)
{
case 1:
case 2:
case 3:
 Do something
 break;
}
switch (x)
{
case 1:
    Some code
case 2:
    Some more code
case 3:
    Even more code
    break;
}
在我看来,这可以使用if/else结构重写,而不会有任何损失


我的最后一句话:不要像坏例子中那样使用掉壳标签,除非您要在使用这种样式并且很容易理解的地方维护遗留代码。

这是一把双刃剑。它有时非常有用,但往往很危险

什么时候好?当你想要10个案件都以同样的方式处理

switch (c) {
  case 1:
  case 2:
            ... Do some of the work ...
            /* FALLTHROUGH */
  case 17:
            ... Do something ...
            break;
  case 5:
  case 43:
            ... Do something else ...
            break;
}

我喜欢的一条规则是,如果你做了任何想排除中断的事情,你需要一条清晰的注释/*错误提示*/以表明这是你的意图。

我不喜欢我的
开关
语句出现错误-它太容易出错,而且很难阅读。唯一的例外是当多个
case
语句都执行完全相同的操作时


如果有一个开关语句的多个分支想要使用的通用代码,我将它提取到一个可以在任何分支中调用的单独的公共函数。

这可能取决于您考虑的故障。我同意这类事情:

开关(值)
{
案例0:
结果=零位;
打破
案例1:
案例3:
案例5:
案例7:
案例9:
结果=奇数;
打破
案例2:
案例4:
案例6:
案例8:
结果=偶数;
打破
}
<>但是如果你有一个案例标签,接着是一个代码,它会落到另一个标签上,我几乎总是认为那是邪恶的。也许将公共代码移动到函数中,并从两个位置调用会是一个更好的主意


请注意,我使用了

的定义,它有时非常有用,但总的来说,没有失败是需要的行为。应该允许失败,但不能含蓄

例如,要更新某些数据的旧版本,请执行以下操作:

switch (version) {
    case 1:
        // Update some stuff
    case 2:
        // Update more stuff
    case 3:
        // Update even more stuff
    case 4:
        // And so on
}

只有当它被用作跳转到代码块中的跳转表时,才应该使用Fall-through。如果代码中有任何部分在更多案例之前无条件中断,则所有案例组都应以这种方式结束


其他任何东西都是“邪恶的”。

我希望交换机中的回退使用不同的语法,比如,errr

switch(myParam)
{
  case 0 or 1 or 2:
    // Do something;
    break;
  case 3 or 4:
    // Do something else;
    break;
}
注意:如果您使用标志声明枚举中的所有案例,这在枚举中已经是可能的,对吗?听起来没那么糟