答案 0 :(得分:13)
答案 1 :(得分:7)
答案 2 :(得分:5)
答案 3 :(得分:4)
答案 4 :(得分:3)
goto
对于执行以下操作非常有用:
foreach ($items as $item) {
if ($item->is_match()) goto match;
}
$item = new Item();
match:
render('find_item.php', $item);
与此相反:
$matching_item = null;
foreach ($items as $item) {
if ($item->is_match()) {
$matching_item = $item;
break;
}
}
if ($matching_item === null) {
$item = new Item();
}
render('find_item.php', $item);
答案 5 :(得分:3)
由于还没有人提出这个问题的答案,OP认为可以接受,我会戴上帽子。
......代码结构之间的基本概念差异 以下两个代码片段?
您提供的两个代码段之间没有概念差异。在这两种情况下都会测试一个条件,如果满足条件,则会向程序的另一部分抛出一条消息进行处理。
为什么第一个被认为是辉煌的而后一个被认为是 是最致命的罪?
感谢Shrapnel上校打开以下咆哮的大门。
<咆哮>
每个编程结构都存在滥用的可能性。对goto
的教条迫害让我想起了类似的对PHP的抨击。 PHP导致错误的编程实践。与以下相比: Goto导致意大利面条代码。
简单地说:goto
是“邪恶的”,因为Edsger Dijkstra这样说并且Niklaus Wirth给了他批准的印章。 ;-p
< /咆哮>
为了您的阅读乐趣:http://en.wikipedia.org/wiki/Goto
可能最着名的批评GOTO的是1968年Edsger的一封信 Dijkstra称 Go To Statement被认为是有害的。在那封信中 Dijkstra认为应废除不受限制的GOTO声明 来自高级语言,因为它们使任务变得复杂 分析和验证程序的正确性(特别是 那些涉及循环)。另一种观点出现在 唐纳德克努特的结构化编程与转到声明 分析许多常见的编程任务,并在其中一些中发现 GOTO是使用的最佳语言结构。
接着说,
一些程序员,例如Linux内核设计师和编码器Linus Torvalds或软件工程师和书籍作者Steve McConnell也是 反对Dijkstra的观点,指出GOTO可能是有用的 语言功能,提高程序速度,大小和代码清晰度, 但只有在相对明智的情况下才以合理的方式使用 程序员。
那就是说,自从Commodore BASIC以来,我个人没有找到GOTO的实际用途,但这既不是在这里也不是在那里。 : - )
答案 6 :(得分:2)
答案 7 :(得分:2)
“错误”的是goto
它可以实现多种控制机制,而不仅仅是throw
,因此几乎没有固有的结构。因此,脚本程序员有兴趣使用goto
替代方案有几个原因:
首先,我们开始看到脚本从纯粹解释转换为字节码编译。可以在任何地方找到这方面的好例子,例如Python,Perl 6,Scala(Lift),Clojure(Compojure)。甚至PHP都有字节码编译器。由于goto
结构很少,控制机制的编译不可能发生,这是一个相当大的性能损失,因为现代编译器通常非常擅长这一点。对于throw
,编译器可以开始假设抛出的异常不常见,因此它将优化“正常”控制路径,通常以不太理想的“异常”控制路径为代价。
即使您没有完整的编译器,当程序员使用具有更多结构的控制机制时,解释器也可以为程序员提供更多帮助。例如,for
循环块由编译器/解释器在词法上作用域,因此程序员可以使用此作用域来模块化代码块。否则,使用goto
,您将被迫污染变量名称空间。
此外,如果您的语言允许您声明throw
异常的方法,编译器/解释器可以通知您没有处理您调用的方法可能遇到的所有可能异常(类似于{ {1}} Java,如果你有经验那里)。对于throws
,编译器不知道你要做什么,所以在编译和测试期间它不会帮助你。
Goto还要求程序员从错误中恢复。想象一下,如果你有一些这样的代码(从你的代码片段中抢夺和编辑):
goto
这里的问题是程序员必须做正确的事情。如果他忘记了if (!isset($a)) {
$message = '$a is not set';
goto errorA;
}
if (!isset($b)) {
$message = '$b is not set';
goto errorB;
}
if (!moonInRightPhase) {
goto errorP
}
echo '$a + $b = '.($a + $b)."<br>\n";
errorA:
// Do something non-trivial and unique to handle $a not being set.
goto afterError
errorP:
// Do something non-trivial and unique to handle moon phase
// This error requires drastic failure of code path:
goto failure
errorB:
// Do something non-trivial and unique to handle $b not being set.
goto afterError
afterError:
// Program continues
return SUCCESS
failure:
return FAILURE
,他将会遇到下一个异常路径。使用goto afterError
时,机制不容易出错。
最后,我个人的经历让我不喜欢throw
陈述,因为它不容易阅读。当我尝试使用名为goto
,some-error
,fail
的四个或五个标签来理解一段代码时,它们并不靠近有问题的/除外代码,它解开可能是一场噩梦。如果它不容易阅读,那么即使程序员试图回顾他或她一年前所做的事情也可能导致错误。
作为这个答案的后脚本,我不认为“错误”是描述retry
的正确方法。这可能来自于着名的Dijkstra论文的耸人听闻。 “强大”可能是一个更好的术语,因为它暗示它几乎可以做任何事情,但即使是最简单的错误也会使“错误”变成“可怕的错误”。我们不应该禁止工具,因为它们真的很危险;我们应该更好地教育人们他们的危险,让他们决定。
答案 8 :(得分:1)
答案 9 :(得分:0)
答案 10 :(得分:-3)