为什么Go语言有一个 “goto” 语句?

huangapple go评论148阅读模式
英文:

Why does Go have a "goto" statement?

问题

我很惊讶地发现Go语言有一个'goto'语句。我一直被教导说'goto'语句是过去的事物,对于程序的实际流程来说是有害的,而函数或方法始终是更好的控制流程的方式。

我一定是漏掉了什么。为什么Google要包含它呢?

英文:

I was surprised to find that Go has a 'goto' statement. I've always been taught that 'goto' statements are a thing of the past and evil for it occludes the actual flow of a program, and that functions or methods are always a better way of controlling flow.

I must be missing something. Why did Google include it?

答案1

得分: 106

当我们实际检查Go标准库的源代码时,我们可以看到goto在哪些地方被实际应用。

例如,在math/gamma.go文件中,使用了goto语句

  for x < 0 {
    if x > -1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }
  for x < 2 {
    if x < 1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }

  if x == 2 {
    return z
  }

  x = x - 2
  p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
  q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
  return z * p / q

small:
  if x == 0 {
    return Inf(1)
  }
  return z / ((1 + Euler*x) * x)
}

在这种情况下,goto语句使我们避免引入另一个(布尔)变量仅用于控制流,并在最后进行检查。在这种情况下goto语句使代码实际上更易于阅读和理解(与你提到的反对goto的论点相反)。

还要注意,goto语句有一个非常特定的用例。关于goto的语言规范指出,它不能跳过进入作用域(被声明)的变量,并且不能跳入其他(代码)块。

英文:

When we actually check the source code of the Go standard library, we can see where gotos are actually well applied.

For example, in the math/gamma.go file, the goto statement is used:

  for x < 0 {
    if x > -1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }
  for x < 2 {
    if x < 1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }

  if x == 2 {
    return z
  }

  x = x - 2
  p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
  q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
  return z * p / q

small:
  if x == 0 {
    return Inf(1)
  }
  return z / ((1 + Euler*x) * x)
}

The goto in this case saves us from introducing another (boolean) variable used just for control-flow, checked for at the end. In this case, the goto statement makes the code actually better to read and easier follow (quite in contrary to the argument against goto you mentioned).

Also note, that the goto statement has a very specific use-case. The language specification on goto states that it may not jump over variables coming into scope (being declared), and it may not jump into other (code-)blocks.

答案2

得分: 41

Goto是一个很好的想法,当内置的控制特性都不能完全满足你的需求时,而且当你可以用goto来表达你想要的时候。(在某些语言中,当你没有goto时,你最终会滥用某些控制特性,使用布尔标志,或者使用比goto更糟糕的其他解决方案,这是一种遗憾。)

如果其他控制特性(以合理明显的方式使用)可以实现你想要的功能,你应该优先使用它,而不是goto。如果不能,就要勇敢地使用goto!

最后值得注意的是,Go语言的goto有一些限制,旨在避免一些隐晦的错误。请参阅规范中的这些限制。

英文:

Goto is a good idea when none of the built-in control features do quite what you want, and when you can express what you want with a goto. (It's a shame in these cases in some languages when you don't have a goto. You end up abusing some control feature, using Boolean flags, or using other solutions worse than goto.)

If some other control feature (used in a reasonably obvious way) can do what you want, you should use it in preference to goto. If not, be bold and use goto!

Finally it's worth noting that Go's goto has some restrictions designed to avoid some obscure bugs. See these restrictions in the specification.

答案3

得分: 15

自从60年代和70年代的意大利面代码时代以来,Goto语句受到了很多贬低。当时几乎没有软件开发方法论。然而,Goto本身并不是邪恶的,但当然可以被懒惰或技术不熟练的程序员滥用和误用。滥用Goto的许多问题可以通过开发流程(如团队代码审查)来解决。

goto是一种与continuebreakreturn相同技术方式的跳转。有人可能会争论这些语句以同样的方式是邪恶的,但事实并非如此。

Go团队为什么包含了Goto可能是因为它是一种常见的流程控制原语。此外,他们希望得出结论,Go的范围不包括创建一个无法滥用的智能安全语言。

英文:

Goto statements has received a lot of discredit since the era of Spaghetti code in the 60s and 70s. Back then there was very poor to none software development methodology. However Goto are not natively evil but can of course be misused and abused by lazy or unskilled programmers. Many problems with abused Gotos can be solved with development processes such as team code reviews.

goto are jumps in the same technical manner as continue, break and return. One could argue that these are statements are evil in the same manner but they are not.

Why the Go team has included Gotos are probably because of the fact that it is a common flow control primitive. Additionally they hopefully concluded that the scope of Go excludes making an idiot-safe language not possible to abuse.

huangapple
  • 本文由 发表于 2012年6月16日 23:58:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/11064981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定