使用“goto”在开关中?
我看到了一个建议的编码标准,内容为除非在 switch 语句中失败,否则永远不要使用 goto
。
我不跟。这个“异常”情况到底是什么样子,才能证明 goto 是合理的?
I've seen a suggested coding standard that reads Never use goto unless in a switch statement fall-through
.
I don't follow. What exactly would this 'exception' case look like, that justifies a goto
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
此构造在 C# 中是非法的:
在 C++ 中,如果
variable = 2
,它将运行两行。这可能是故意的,但很容易忘记第一个 case 标签末尾的break;
。因此,他们在 C# 中将其定为非法。要模仿跌倒行为,您必须明确使用goto
来表达您的意图:也就是说,有 一些情况,其中
goto
实际上是解决该问题的一个很好的解决方案。 永远不要用“永远不要使用某些东西”的规则来关闭你的大脑 。如果它 100% 无用,那么它从一开始就不会存在于语言中。不要使用goto
是指南;这不是法律。This construct is illegal in C#:
In C++, it would run both lines if
variable = 2
. It may be intentional but it's too easy to forgetbreak;
at the end of the first case label. For this reason, they have made it illegal in C#. To mimic the fall through behavior, you will have to explicitly usegoto
to express your intention:That said, there are a few cases where
goto
is actually a good solution for the problem. Never shut down your brain with "never use something" rules. If it were 100% useless, it wouldn't have existed in the language in the first place. Don't usegoto
is a guideline; it's not a law.C# 拒绝让 case 隐式失败(除非 case 中没有代码),就像 C++ 中一样:您需要包含
break
。要明确失败(或跳转到任何其他情况),您可以使用goto case
。由于没有其他方法可以实现这种行为,因此大多数(合理的)编码标准都允许这样做。一个现实的例子(根据要求):
C# refuses to let cases fall through implicitly (unless there is no code in the case) as in C++: you need to include
break
. To explicitly fall through (or to jump to any other case) you can usegoto case
. Since there is no other way to obtain this behaviour, most (sensible) coding standards will allow it.A realistic example (by request):
这
比这更简洁(特别是如果您在 Quit() 中做了更多工作)
This is neater
Than this (especially if you do more work in Quit())
除了使用
goto case
之外,您还可以goto
另一个 case 子句中的标签:这样,您就可以跳转到另一个 case 子句,而不必担心值或类型的表达式。
不过,某种可以替代
break
的显式“fallthrough”关键字会很好......In addition to using
goto case
, you cangoto
a label that is in another case clause:This way, you can jump to another case clause without worrying about the value or type of the expression.
Some sort of explicit "fallthrough" keyword that can be substituted for
break
would have been nice, though...这是 C# 允许 switch case “失败”的唯一方法。在 C# 中(与 C、C++ 或 Java 不同),switch 语句中的 case 块必须以
break
或其他显式跳转语句结束。It's the only way that C# allows a switch case 'fallthrough'. In C# (unlike C, C++ , or Java), a case block in a switch statement must end with a
break
or some other explicit jump statement.通过对 Mehrdad Afshari 上述建议的扩展,我绝不会主张简单地将某个构造作为“糟糕的代码”或“糟糕的编码实践”而放逐。甚至“goto”语句在宏伟的计划中也占有一席之地。认为它们是邪恶的教条之所以成为现实,并不是因为结构中存在任何固有的缺陷——而是因为它们被严重(且糟糕地)过度使用。
无论如何,克尼根和里奇认为,让案件败诉才是正确的做法。坦率地说,我更倾向于相信他们的推理,而不是整个华盛顿雷德蒙德任何人的想法。或者任何基于雷德蒙德任何人的智慧的教条。
如果您听到“永远不要使用 xxx”,请在心里加上“无原因”。教条地抛弃任何东西都是荒谬的。设备的存在是因为有制造它们的理由。事后看来,它们通常被称为“坏”,不是因为设备本身有任何故障,而是因为不完全理解它们的人对它们的使用不当。因此,该设备几乎不会“坏”。几乎总是不好的就是用户的理解能力。即使对于原子裂变和聚变也是如此。
我见过一些极其怪异的代码结构,其唯一的功能就是避免使用“goto”语句。更糟糕的是什么呢? “goto [label]”,还是 30 行恶心的代码,其功能是避免键入“goto [label]”?
在教条之前寻求知识。行动前三思。这些都是有用的建议。
By way of an extension to Mehrdad Afshari's advice above, I would never advocate simply exiling a construct as 'bad code' or 'bad coding practice'. Even 'goto' statements have their place in the grand scheme of things. The dogma that they are evil did not come to pass because of any inherent flaw in the construct - it was because they were heavily (and poorly) over-used.
In any case, Kernighan and Ritchie felt that allowing a case to fall through was the proper way to go. Frankly, I'm more inclined to trust their reasoning than anything that could conceivably come out of any mind in the whole of Redmond, Washington. Or any dogma that is predicated on the wisdom of any mind in Redmond.
If you ever hear 'Never use xxx', mentally append that with 'without cause'. Just tossing out anything dogmatically is ridiculous. Devices exist because there was a reason to make them. They are, in hindsight, usually referred to as 'bad' not because of any fault in the device itself, but rather because they were employed poorly by people who did not fully understand them. Thus, the device is hardly ever 'bad'. What is almost always bad is user comprehension. This is true even of atomic fission and fusion.
I've seen horrendously grotesque code structures whose sole function was to avoid the use of a 'goto' statement. What is worse? "goto [label]", or 30 lines of disgusting code whose function is to avoid having to type "goto [label]"?
Seek knowledge before dogma. Think before you act. These are useful advices.
我知道这是老话题,但问题仍然是现实的。我们可以使用下一个代码而不是带有 goto 语句的丑陋版本吗?
可能会被替换为下一个更简洁的代码:
I know that is old topic but question is still actual. Could we use the next code instead ugly version with goto statement ?
might be substituted with the next neater code: