141

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?

4

3 回答 3

99

当我们实际查看 Go 标准库的源代码时,我们可以看到gotos 实际应用得很好。

例如,在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 上的语言规范声明它可能不会跳过进入范围(被声明)的变量,也可能不会跳转到其他(代码)块。

于 2012-06-16T17:24:00.327 回答
37

当没有任何内置控制功能完全满足您的需求,并且您可以使用 goto 表达您想要的内容时,Goto 是一个好主意。(在某些语言中,当您没有 goto 时,这是一种耻辱。您最终会滥用某些控制功能,使用布尔标志或使用比 goto 更糟糕的解决方案。)

如果其他一些控制功能(以相当明显的方式使用)可以做你想做的事,你应该优先使用它而不是 goto。如果没有,请大胆使用 goto!

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

于 2012-06-16T17:08:10.357 回答
12

自从60 和 70 年代的意大利面条代码时代以来,Goto 语句就受到了很多质疑。那时,软件开发方法非常差,甚至没有。然而,Goto 本身并不是邪恶的,但当然可以被懒惰或不熟练的程序员误用和滥用。许多滥用 Goto 的问题都可以通过团队代码审查等开发流程来解决。

goto是以与和相同的技术方式continue跳跃。有人可能会争辩说,这些陈述以同样的方式是邪恶的,但事实并非如此。breakreturn

Go 团队之所以包含 Goto,可能是因为它是一种常见的流控制原语。此外,他们希望得出结论,Go 的范围不包括使白痴安全语言不可能被滥用。

于 2016-02-16T20:26:41.867 回答