我惊讶地发现Go带有“ goto”语句。我一直被教导说,“ goto”语句已经成为过去,并且因为它阻塞了程序的实际流程,所以它变得邪恶,并且函数或方法始终是控制流程的更好方法。
我肯定错过了什么。Google为什么要包含它?
我惊讶地发现Go带有“ goto”语句。我一直被教导说,“ goto”语句已经成为过去,并且因为它阻塞了程序的实际流程,所以它变得邪恶,并且函数或方法始终是控制流程的更好方法。
我肯定错过了什么。Google为什么要包含它?
Answers:
当我们实际检查Go标准库的源代码时,我们可以看到goto
s在哪些地方得到了很好的应用。
例如,在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的语言规范指出,它可能不会跳过进入范围(被声明)的变量,并且可能不会跳过其他(代码)块。
small(x,z)
来代替呢?这样,我们不必考虑small:
标签中可以访问哪些变量。我怀疑原因是go仍然缺少编译器中某些类型的内联支持。
goto
引入新变量后,@ ThomasAhle Go不允许指向标签。执行“ goto”语句一定不能使任何变量在goto时尚未进入作用域。
自从60年代和70年代的意大利面条式代码时代以来,Goto语句就受到了很多声名狼藉。那时,几乎没有软件开发方法。但是,Goto并不是天生的邪恶,但是当然可以被懒惰或不熟练的程序员滥用和滥用。滥用Gotos的许多问题可以通过开发过程来解决,例如团队代码审查。
goto
在相同的技术方式的跳跃continue
,break
和return
。有人可能会说,这些陈述以同样的方式是邪恶的,但事实并非如此。
Go团队之所以将Gotos包括在内,可能是因为它是常见的流控制原语。此外,他们希望得出结论,围棋的范围不包括使白痴安全的语言无法被滥用。
continue
,,break
和return
在一个关键方面有很大不同:它们仅指定“离开封闭范围”。它们不仅鼓励而且明确要求开发人员考虑其代码结构,并依赖结构化的编程原语(用于循环,函数和switch语句)。goto
语句唯一且唯一可以节省的地方是,它们允许您在编译器的优化器无法完成任务时使用HLL编写程序集,但这是以可读性和可维护性为代价的。
setjmp
,longjmp
,goto
,和try / except / finally
他们选择犯错就在身边小心点 goto
首先,是默认的“结构化编程”控制流程。