时间:2010-07-25 13:45:22

标签: php exception-handling try-catch goto

11 个答案:

答案 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陈述,因为它不容易阅读。当我尝试使用名为gotosome-errorfail的四个或五个标签来理解一段代码时,它们并不靠近有问题的/除外代码,它解开可能是一场噩梦。如果它不容易阅读,那么即使程序员试图回顾他或她一年前所做的事情也可能导致错误。

作为这个答案的后脚本,我不认为“错误”是描述retry的正确方法。这可能来自于着名的Dijkstra论文的耸人听闻。 “强大”可能是一个更好的术语,因为它暗示它几乎可以做任何事情,但即使是最简单的错误也会使“错误”变成“可怕的错误”。我们不应该禁止工具,因为它们真的很危险;我们应该更好地教育人们他们的危险,让他们决定。

答案 8 :(得分:1)

答案 9 :(得分:0)

答案 10 :(得分:-3)