在交换机中使用“goto”?

我已经看到一个build议的编码标准,读取Never use goto unless in a switch statement fall-through

我不跟随。 这个“例外”情况究竟是什么样子,certificategoto是正当的?

这个构造在C#中是非法的:

 switch (variable) { case 2: Console.WriteLine("variable is >= 2"); case 1: Console.WriteLine("variable is >= 1"); } 

在C ++中,如果variable = 2 ,它将运行两行。 这可能是故意的,但是很容易忘记break; 在第一个案例标签的末尾。 出于这个原因,他们已经在C#中违法了。 为了模仿通过行为的失败,你必须明确地使用goto来expression你的意图:

 switch (variable) { case 2: Console.WriteLine("variable is >= 2"); goto case 1; case 1: Console.WriteLine("variable is >= 1"); break; } 

也就是说,有几种情况下goto实际上是一个很好的解决scheme。 永远不要用“从不使用某些东西”的规则来closures你的大脑 。 如果它是100%无用的,那么语言本来就不存在。 不要使用goto是一个准则 ; 这不是一个法律。

C#拒绝让案例在C ++中隐含(除非案例中没有代码):你需要包含break 。 要明确地通过(或跳转到任何其他情况),你可以使用goto case 。 由于没有其他的方式来获得这种行为,大多数(明智的)编码标准将允许它。

 switch(variable) { case 1: case 2: // do something for 1 and 2 goto case 3; case 3: case 4: // do something for 1, 2, 3 and 4 break; } 

一个现实的例子(按要求):

 switch(typeOfPathName) { case "relative": pathName = Path.Combine(currentPath, pathName); goto case "absolute"; case "expand": pathName = Environment.ExpandEnvironmentVariables(pathName); goto case "absolute"; case "absolute": using (var file = new FileStream(pathName)) { ... } break; case "registry": ... break; } 
  public enum ExitAction { Cancel, LogAndExit, Exit } 

这很整洁

 ExitAction action = ExitAction.LogAndExit; switch (action) { case ExitAction.Cancel: break; case ExitAction.LogAndExit: Log("Exiting"); goto case ExitAction.Exit; case ExitAction.Exit: Quit(); break; } 

比这个(特别是如果你在Quit()中做更多的工作)

 ExitAction action = ExitAction.LogAndExit; switch (action) { case ExitAction.Cancel: break; case ExitAction.LogAndExit: Log("Exiting"); Quit(); break; case ExitAction.Exit: Quit(); break; } 

这是C#允许开关盒“贯穿”的唯一方法。 在C#中(与C,C ++或Java不同),switch语句中的case块必须以break或其他显式跳转语句结尾。

除了使用goto case ,还可以在另一个case子句中find一个标签:

  switch(i) { case "0": // do some stuff break; case "1": // other stuff, then "fall through" to next case clause goto Case2; case "2": Case2: break; } 

这样,您可以跳到另一个case子句,而不必担心expression式的值或types。

一些明显的“fallthrough”关键字,可以代替break会很好,虽然…

通过对Mehrdad Afshari上述build议的扩展,我绝不会主张简单地将一个构造放逐为“坏代码”或“坏编码实践”。 甚至'goto'的陈述在事物的macros伟计划中占有一席之地。 他们是邪恶的教条没有成功,因为这个build筑存在固有的缺陷 – 那是因为他们过度使用(而且很less)。

无论如何,Kernighan和Ritchie认为允许案件通过是正确的方法。 坦率地说,我更倾向于相信他们的推理,而不是整个华盛顿州雷蒙德市的任何想法。 或者任何以雷德蒙德任何思想的智慧为依据的教条。

如果您听到“永远不要使用xxx”,请在“无缘”的情况下将其附加在心里。 只是教条抛出什么是荒谬的。 设备的存在是因为有理由做出来。 事后看来,他们通常被称为“坏”,不是因为设备本身的任何错误,而是因为他们被不完全了解他们的人雇用得不好。 因此,该设备几乎不“坏”。 用户理解几乎总是不好的。 即使是primefaces分裂和聚变也是如此。

我已经看到了可怕的怪诞的代码结构,其唯一的function是避免使用“goto”语句。 什么更糟? “goto [label]”,或30行令人厌恶的代码,其function是避免input“goto [label]”?

在教条之前寻求知识。 三思而后行。 这些是有用的build议。