18

“goto”语句直接来自 ASM 或任何其他汇编语言。

这是一个链接:http ://be2.php.net/manual/en/control-structures.goto.php

我想知道:这可以使我的代码更有条理吗?我怎样才能在更大的项目中实现这一点,而不会搞砸。由于 goto 将允许您来回跳转,因此如果您以错误的方式使用它,意外分配和无限循环正在等待发生。

有人可以给我一个很好地使用它的例子吗?

编辑:好吧,我已经看到了一些回复,显然对于“goto”语句的使用存在广泛的共识,而且它很糟糕。

所以我仍然想知道:为什么 PHP 会费心将它添加到语言中。如果他们没有看到其中的东西,他们就不会这样做……那为什么呢?

另外:StackOverflow 上关于“goto”的一般讨论

EDIT2:看到这个问题导致很多不好的事情对 goto 语句感到难过,我去问了我的父亲。他今年 52 岁,是一名工业工程师。
他告诉我几次,他在他的日子里做了很多编程,主要是在 FORTRAN 和 COBOL 中。现在他做IT服务、服务器和网络管理等。

不管怎样,他说了一些“回到我的时代……”
讨论了一下之后,他回到了 goto 语句,说即使回到他学生时代,他们就已经知道这不是一个聪明的使用它的想法,但他们当时并没有更好的选择。Try/catch 还需要几年的时间,而且几乎没有消除错误处理。
那么你做了什么来检查你的程序?在末尾添加几行,允许您打印输出以及您需要在代码中检查的所有内容,然后放置以下行:“goto printing;”或类似的内容,以开始打印数据。

并且以这种方式,您逐渐调试了您的代码。

他同意在现代编程世界中使用 goto 是毫无用处的。他认为唯一合理的用途是“紧急中断”,用于极端调试和意外情况。有点像goto fatal_error;,并让代码的“fatal_error”部分做一些事情来向您展示深入的结果。
但仅限于创建某些东西的过程中。成品不应该有 goto 语句。

后期编辑:关于 PHP5.3/PHP6 中“goto”的另一个讨论

4

16 回答 16

14

如果您正在编写好的 PHP 代码,则不需要使用 goto。我认为他们添加它是一个错误,因为它只会导致懒惰的编程。

http://www.procata.com/blog/archives/2004/07/29/goto-in-php/

有关将 this 添加到 PHP 以及此处有关堆栈溢出的良好评论,

GOTO 仍然被认为是有害的?

于 2009-04-06T21:37:21.243 回答
11

我只发现了两种用途goto

  1. 打破嵌套循环。但是大多数较新的语言都有一种机制可以做到这一点,goto无论如何(break <number>在 PHP 或break <loop label>Java 等中)。
  2. 转到函数末尾的清理部分。但同样,这在垃圾收集语言中通常并不有用。

换句话说,如果你不知道你是否应该使用goto某事,你不应该。

于 2009-04-06T21:38:14.393 回答
3

我在语言中看到 goto 的主要用途是跨语言移植的能力。我用 C 语言编写了一个解析器生成器,它生成带有 goto 的解析器(因为使用 goto 比实现更健全的控制结构更容易),现在将它移植到 PHP 并没有那么令人头疼。

于 2010-05-31T07:24:25.940 回答
3

goto 可以帮助减少堆栈展开的代码重复,在下面的伪代码中:

do A
if (error)
    goto out_a;
do B
if (error)
    goto out_b;
do C
if (error)
    goto out_c;
goto out;

out_c:
undo C

out_b:
undo B:

out_a:
undo A

out:
return ret;

(Robert Love 的伪代码,取自 linux 内核归档邮件列表: https ://lkml.org/lkml/2003/1/12/203 )

于 2011-07-16T00:19:15.573 回答
2

它可用于调试目的,因此您不必为了临时更改工作流程而注释或重构代码块。

于 2009-04-06T23:46:53.740 回答
2

在经典 VB 编码中,使用 goto 可以方便地模拟 try/catch 错误处理,如下所示:

Function MyFunction() as String

'-- start of error block
'
 On Error Goto Catch
   ' do something here that might cause an error
   MyFunction = "IT WORKED"
   Exit Function

 Catch:
   ' error occured - do something else
   MyFunction = Err.Description

 '
 '-- end of error block

End Function

...这是一种模拟 try/catch/finally 的方法 ..

Function MyFunction() as String

'-- start of error block
'
 On Error Goto Catch
   ' do something here that might cause an error
   MyFunction = "IT WORKED"
   Goto Finally

 Catch:
   ' error occured - do something else
   MyFunction = Err.Description
   Err.Clear

 Finally:
   ' put your finally code here

 '
 '-- end of error block

End Function

它对于函数末尾的清理也很有用,尽管我想你可以提出一个可以调用另一个函数来进行清理的案例。

老实说,我在 PHP 中从来没有遇到过这样的情况:我想‘嗯,我希望有一个 goto 语句’。我还没有了解他们为什么决定这样做,但是,这些人非常聪明,并且到目前为止已经将 PHP 带入了非常好的方向,所以也许他们正在预测我们尚未意识到的需求。

于 2009-04-07T13:53:33.190 回答
1

没有很好地使用 goto 之类的东西。

也许,只是也许,摆脱多个嵌套循环可能很有用,但你已经可以使用“break 2”等来做到这一点。为此,像 Java 中的标记中断会比 goto 更好。

当您需要在一个失败时跳到一堆语句的末尾时,它可能对不使用异常编写的代码也很有用。但这只是用更糟糕的代码来修复糟糕的代码。

于 2009-04-06T21:33:38.803 回答
1

我承认我从未在我的代码中使用过 goto。:)

对我来说,唯一的原因似乎是促进了从其他语言到 PHP 的最短迁移路线(实际上只是在不触及控制结构的情况下更改语言)并在移植的第二阶段重构代码。

我个人相信受过教育的同事,因为他们可以避免循环中的条件中断,他们将能够抵制 goto 的诱惑。

于 2009-04-07T10:53:20.050 回答
1

Goto 主要用于编写有限状态机。在解析上下文无关语法时,您实际上需要其中之一。尽管我们可以不用 goto ifcontinue $case;是 switch 块中的一个有效语句来跳转到不同的案例,并且当然具有当今许多语言所具有的案例范围。在那之前,我们几乎都被 goto 困住了。

于 2010-09-28T14:30:19.870 回答
1

有时我goto用来避免多个嵌套的 if。这不仅与逻辑、结构或程序流程有关,有时还可能与代码的外观有关。

于 2017-08-31T13:11:39.557 回答
0

goto确实应该是语言中的东西,并且由于更好的编程实践而将被淘汰。现在添加它似乎是倒退。

于 2009-04-06T23:56:20.520 回答
0

我猜,生成的代码可以很好地利用 goto。生成代码的好处是您不需要维护它 - 您只需重新生成它。

于 2009-12-14T11:23:03.870 回答
0

goto 的最大优势是学习曲线。人们想知道为什么 Visual studia 和 mac 等工具表现出色。原因是人们想要的不仅仅是伟大的产品。他们想要一个很棒的产品,他们可以在一个小时左右的时间内学会使用。许多程序员现在只是将编程作为他们的工作之一。我看到很多书都说永远不应该使用 goto,然后给出五种左右的技术,这样他们就说消除了对它的所有需求。我说他们提到 5 的事实证明了 goto 有多好!!!!!!我没有时间教五件事,其中包括需要整章解释的异常结构!!!!!!!当你真正需要的是一个可以在 30 秒内解释的简单 goto 时。当然,如果程序员愿意,你可以用它们创建糟糕的代码——但是,嘿,大多数程序员都不会 不想编写糟糕的代码,如果他们这样做了,他们无论如何都可以。我们实验室的大多数 goto 使代码非常易于理解和学习;比阅读一本 2000 页的书要重要得多。

于 2013-07-27T04:34:08.767 回答
0

GOTO 是受限制的执行控制结构,可以用来代替循环,但非常不鼓励这样做。它的使用往往会鼓励创建非结构化代码,这是一种糟糕的做法。如果仅用于开发、调试(跳过大量代码以访问特定问题区域)和测试,它很可能是最好的。GOTO 的唯一其他用途可能是编写汇编程序。不见得。如果在开发之外使用 GOTO,则应谨慎使用,并且仅作为最后的手段。如果可能,将 GOTO 替换为适用的循环结构。

至于最后链接的线程(PHP 中的 GOTO 命令?):

正如 Ishmaeel 所说(由 Gordon 编辑;迄今为止最好的答案):

GOTO 只是一个扩展的 BREAK,具有“使用静态标签”的能力。“基本上,它将增强突破嵌套 if 语句的能力。”

于 2014-11-13T18:20:35.997 回答
0

简短的回答是 goto 是有限堆栈空间的解决方法,在单线程代码中具有更好的性能。除了处理堆栈空间或性能之外,它的使用至少是不必要的,最多是不合适的,因为它会导致不必要的复杂性。

在我用所有语言编写的超过 200 万行代码中,不包括机器代码 :-)。只有两次使用它是必要的,而且都是由于检查\排序大型树数据集。

于 2017-04-21T23:09:07.633 回答
-1

如前所述,goto 仅在某些类型的算法中真正需要,通常是那些出现在语言解析或有限状态机中的算法。我从未错过 PHP 中缺少 goto。

OTOH,我用一种语言编程,其中只有两个结构是函数和条件 goto:SNOBOL4。由于意大利面条代码的风险如此之高,因此大多数 SNOBOL4 程序员都小心翼翼地避免这种情况。但是 gotos 确实实现了一些非常紧凑的编程、创造性的循环执行等等。如果您只有 goto,那么执行 FSM 类型的循环实际上会更容易一些。

于 2009-04-07T00:44:22.743 回答