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