75

我最近发现 PHP 5.3 支持名为GOTO. 每个人都知道它的作用。但是,它并不完全是传统的GOTO,它只是一个跳转标签。我很想知道这是否GOTO是邪恶的并暗示了错误的代码?

4

11 回答 11

157

除非您使用汇编程序进行编程,否则 GOTO 应该始终像飞机的救生衣一样被对待:拥有它们是很好的,但如果您需要使用它们,则意味着您遇到了大麻烦。

于 2009-12-14T10:12:54.203 回答
104

我不敢相信没有人发布这个:)

xkcd - 转到

当然,PHP 没有被编译……也许猛禽会在每次访问您的网站时追赶您?

于 2009-12-14T10:30:39.970 回答
84

无论您使用哪种控制结构,糟糕的代码结构都是邪恶的。

我个人更喜欢一个 goto,它可以明确程序流到“控制变量”和嵌套的“if”,这将间接导致代码中的相同分支。

因此,只需编写两个版本(有和没有 GOTO),看看哪个更容易理解。那么选择就很简单了。

于 2009-12-14T10:10:33.350 回答
28

我认为这是PHP 手册页中最重要的部分,但这里缺少:

不是完全不受限制的 goto。目标标签必须在同一个文件和上下文中,这意味着你不能跳出一个函数或方法,也不能跳入一个. 您也不能跳入任何类型的循环或开关结构。你可能会跳出这些,一个常见的用途是使用 goto 代替多级中断。

恕我直言,这使它与ye olde BASIC 风格的 goto非常不同。

于 2013-05-28T22:53:05.943 回答
18

我是少数(目前),但我相信对 PHP 的 goto 构造的限制是一个非常有益的工具:

http://adamjonrichardson.com/2012/02/06/long-live-the-goto-statement/

实际上,我浏览了一个箭头代码示例(深度嵌套的条件),并在一个版本中使用标准做法(保护子句、分组条件、提取函数)重构它,在另一个版本中使用基于 goto 的版本,我实际上更喜欢基于goto的重构。

于 2012-02-06T08:36:59.217 回答
11

枪是邪恶的吗?两者都可以用于善或恶。我会说没有 goto 编写好的代码比使用 goto 更容易。

于 2009-12-14T10:06:47.070 回答
7

任何可以在给定情况下使代码更具可读性的语言特性都是一件好事。GOTO 就是这样一种语言功能,即使这些情况很少见。如果我们禁止任何让糟糕的程序员编写糟糕的、无法维护的代码成为可能的语法,我们的工作就会困难得多。

于 2009-12-14T10:16:35.910 回答
5

作为一名软件工程师,我主要在“大型机”和“大型企业服务器”上工作……而我们的日常语言(我的意思是我们基本代码中 95% 的语言)是 Cobol,它广泛使用 GOTO。

这种用法并不意味着代码不好。这只是意味着这个工具 (GOTO) 在编写程序时是正确的。

为了回答 Kaitsuli 的问题,我认为它在编写 PHP 脚本时可能是有用的工具。另一方面,到现在已经有将近十年的时间了,很多脚本都是在没有它的情况下完成的。此外,它与 PHP 的发展背道而驰,具有更多面向对象的特性。

恕我直言,生成代码既不是好事也不是坏事:好的程序仍然是好的,而“恐怖程序”会更糟……唯一的问题是:“为什么在证明没有必要之后再添加 GOTO 10 年? ”。

于 2009-12-14T10:48:21.230 回答
3

GOTO 通常是邪恶的,因为它可以让您构建非结构化代码。使用通常的循环,您可以构建易于遵循的良好结构化代码,因为它是结构化的。

当你有非结构化代码从这里跳转到那里时,你刚刚发现了来自 GOTO 语句的邪恶。几乎总是最好避免它。也许每 100.000 行就有一次 GOTO 语句简化了很多代码,因此代码并不邪恶,但如果你不确定,那么你应该避免使用 GOTO。

希望这可以帮助。

编辑:好吧,只是在这里添加我自己的观点,还有其他指令允许您创建非结构化代码,并且当我认为它们应该被认为是邪恶时,它们并不被认为是邪恶的。

例如,函数中间的 return 是到它末尾的 GOTO,所以我避免使用它们,并且在每个函数的末尾只使用一个 return。

其他语言,如 Vb.Net(可能还有其他语言)允许执行 Exit For、Exit While、breaks 和类似的事情,这些也使代码不结构化,我认为应该避免。

于 2009-12-14T10:10:42.073 回答
2

有时(我的意思是在 0.01% 的情况下)它很有用,比如当你有一个很长的脚本并且你想测试一些块时。但永远不要将其保留在您的最终脚本中

于 2013-08-26T16:16:09.697 回答
1

我在编写在 cli 模式下工作的脚本时使用了 GOTO。它救了我的命。

于 2013-01-04T11:52:58.137 回答