当前位置:  开发笔记 > 编程语言 > 正文

Switch Statement Fallthrough ...是否允许?

如何解决《SwitchStatementFallthrough是否允许?》经验,为你挑选了7个好方法。

只要我记得我已经避免使用switch语句.实际上,我不记得它曾经进入我的意识作为一种可能的做事方式,因为它早在我的头脑中钻了它只不过是转换语句中的一个错误.然而,今天我遇到了一些在设计中使用它的代码,这让我立刻想知道社区中的每个人都认为有关switch语句的漏洞.

这是编程语言应该明确不允许的东西(比如C#,但它提供了一种解决方法),还是任何语言的功能都足以留给程序员手中?

编辑: 我没有具体到达我的意思.我经常使用这种类型:

    switch(m_loadAnimSubCt){
        case 0: 
        case 1: 
            // Do something
            break;
        case 2:
        case 3:
        case 4:
            // Do something
            break;
   }

但是,我很担心这样的事情.

   switch(m_loadAnimSubCt){
        case 0: 
        case 1: 
            // Do something but fall through to the other cases 
            // after doing it.
        case 2:
        case 3:
        case 4:
            // Do something else.
            break;
   }

这种方式只要大小写为0,1就会在switch语句中执行所有操作.我已经通过设计看到了这一点,我只是不知道我是否同意以这种方式使用switch语句.我认为第一个代码示例非常有用且安全.第二个似乎有点危险.



1> Fred Larson..:

这可能取决于您认为的漏洞.我对这种事情很满意:

switch (value)
{
  case 0:
    result = ZERO_DIGIT;
    break;

  case 1:
  case 3:
  case 5:
  case 7:
  case 9:
     result = ODD_DIGIT;
     break;

  case 2:
  case 4:
  case 6:
  case 8:
     result = EVEN_DIGIT;
     break;
}

但如果你有一个案例标签,后面跟着另一个案例标签的代码,我几乎总是认为这是邪恶的.也许将公共代码移动到一个函数并从两个地方调用将是一个更好的主意.

请注意我使用的C++ FAQ定义 "邪恶"


+1只是为了"邪恶"的定义.我会借用它,谢谢;-)

2> John M..:

这是一把双刃剑.有时非常有用,通常很危险.

什么时候好?当你想要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;
}

我喜欢的一条规则是,如果你做任何想要排除休息的事情,你需要一个明确的评论/*FALLTHROUGH*/表示这是你的意图.


我自己在适当的代码中使用/*FALL THROUGH*/comment.=]
+1!我同意它偶尔会得到正确的答案,而且我同意在设计时它应该被评论.(在代码审查中,我要让其他开发人员评论一个非设计的非空出现.不是说它发生了;我们是一个不支持的C#商店:)
如果你是PC-Lint,你必须插入/* - fallthrough*/,否则它会抱怨.

3> Lucas Oman..:

根据你正在做的事情,堕落真的很方便.考虑这种安排和可理解的方式来安排选项:

switch ($someoption) {
  case 'a':
  case 'b':
  case 'c':
    // do something
    break;
  case 'd':
  case 'e':
    // do something else
    break;
}

想象一下用if/else做这件事.这将是一个烂摊子.



4> tzot..:

你听说过Duff的设备吗?这是使用switch fallthrough的一个很好的例子.

这是一个可以使用的功能,它可以像几乎所有语言功能一样被滥用.


请注意达夫在那篇文章中引用的评论:"这段代码在辩论中形成某种论点,但我不确定它是赞成还是反对."

5> 小智..:

它可能是非常有用的几次,但一般来说,没有穿透是期望的行为.应该允许通过,但不是隐含的.

例如,更新某些数据的旧版本:

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



6> Erik van Bra..:

我喜欢在开关中使用不同的回退语法,比如,errr ..

switch(myParam)
{
  case 0 or 1 or 2:
    // do something;
    break;
  case 3 or 4:
    // do something else;
    break;
}

注意:如果你使用标志声明你的枚举上的所有案例,那么枚举就已经可以了吗?听起来也不是那么糟糕,案件可能(应该?)很好地成为你的枚举的一部分.

对于使用扩展方法的流畅界面,这可能是一个很好的案例(没有双关语)?有点像,错误......

int value = 10;
value.Switch()
  .Case(() => { /* do something; */ }, new {0, 1, 2})
  .Case(() => { /* do something else */ } new {3, 4})
  .Default(() => { /* do the default case; */ });

虽然这可能更不易读:P



7> steffenj..:

与任何事情一样:如果小心使用,它可以是一个优雅的工具.

但是,我认为缺点不仅仅是不使用它,最后也不再允许它(C#).问题包括:

很容易"忘记"休息

对于代码维护者来说,并不总是显而易见的是,省略的中断是故意的

很好地利用了开关/外壳:

switch (x)
{
case 1:
case 2:
case 3:
 do something
 break;
}

BAAAAAD使用开关/案例:

switch (x)
{
case 1:
    some code
case 2:
    some more code
case 3:
    even more code
    break;
}

在我看来,这可以使用if/else结构重写,完全没有任何损失.

我的最后一句话:远离BAD示例中的堕落案例标签,除非您使用这种风格并且很好理解这些样式的遗留代码.


您可以使用if()和goto重新编写大多数语言结构,但这并不能证明放弃显式结构是合理的。
我知道但是切换/案例构造明确使用"案例1:一些代码案例2:更多代码案例3:最终代码中断"; 可以而且应该使用if/else if(我的意见)重写.
推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有