为什么Go有一个“goto”的声明

Google的Go语言是一种新的语言。 因此,我很惊讶地发现它有一个“转到”的声明。 我总是被教导说,'goto'的陈述是过去的事情,它的邪恶阻碍了程序的实际stream程。 function(或方法,如果你愿意的话)总是一个更好的方法来控制stream量。

我肯定错过了什么。 为什么和何时使用'goto'是一个好主意? 或者为什么Google包含它?

当我们实际检查Gos源代码( 标准库 )时,我们可以看到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节省我们引入另一个(布尔)variables只用于控制stream量,最后检查。 在这种情况下goto语句使得代码实际上更好的阅读和更容易遵循(完全相反的反对你提到的goto )。

还要注意, goto语句有一个非常具体的用例。 goto的语言规范规定,它不能跳过进入作用域(被声明)的variables,并且不能跳转到其他(代码)块中。

如果没有内置的控制function完全符合您的要求,并且何时可以用gotoexpression您想要的内容,那么Goto是一个好主意。 (在这些情况下,在某些语言中,如果你没有goto,这是一个耻辱,最终会滥用某些控制function,使用布尔标志或者使用其他比goto更差的解决scheme。

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

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

自上世纪60年代和70年代的意大利面代码时代以来,Goto的声明受到了很多的怀疑。 当时那里的软件开发方法非常差。 然而,后藤并不是天生的邪恶,但当然可以被懒惰或不熟练的程序员滥用和滥用。 滥用Gotos的许多问题可以通过开发stream程(如团队代码审查)来解决。

goto以同样的技术方式跳转, continuebreakreturn 。 人们可以争辩说,这些陈述是同样的恶,但他们不是。

Go团队为什么包含Gotos可能是因为它是一个常见的stream程控制原语。 此外,他们希望得出结论,围棋的范围不包括使一个白痴安全的语言不可能滥用。

据我所知,goto主要用于在单个函数内部实现巨型状态机。 现代软件开发倾向于通过将状态机分成类和多个方法来实现状态机,但是有些人不相信编译器优化他们的代码,所以他们希望手动将所有东西都内联到一个巨大的函数中。

Interesting Posts