Go v.s.中的恐慌恢复尝试用其他语言捕获

时间:2010-08-05 09:29:59

标签: exception error-handling go

我刚刚阅读了关于恐慌/恢复的this post,我不清楚这与其他主流语言中的try / catch有何不同。

5 个答案:

答案 0 :(得分:21)

恐慌/恢复是功能范围。这就像说你在每个函数中只允许一个try / catch块,并且try必须涵盖整个函数。这使得使用Panic / Recover非常烦人,就像java / python / c#等使用异常一样。这是故意的。 这也鼓励人们以设计使用的方式使用恐慌/恢复。你应该从panic()中恢复(),然后将一个错误值返回给调用者。

答案 1 :(得分:18)

我一直在考虑这个问题,试图想出最好的方法来回答它。最简单的方法是指出 panic / recover 的惯用用法,而不是 try / catch & |其他语言中的例外,或这些习语背后的概念(基本上可以概括为“例外应该只在真正特殊情况下发生”)

但至于它们之间的实际区别是什么?我会尽力总结一下。

try / catch 块相比的主要区别之一是控制流的方式。在典型的 try / catch 方案中,catch块之后的代码将运行,除非它传播错误。 panic / recover 并非如此。恐慌中止当前函数并开始展开堆栈,在遇到它们时运行延迟函数(唯一可以恢复的地方)。

真的,我会更进一步:恐慌/恢复几乎与 try / catch 完全不同,因为try和catch是(或至少表现得像)控制结构,恐慌/恢复不是。

这真的源于这样一个事实:恢复是围绕延迟机制建立的,据我所知,这是一个相当独特的概念。

肯定会有更多,如果我能更好地激发我的想法,我会补充一点。

答案 2 :(得分:9)

延迟是一种机制,不仅可以处理错误,还可以进行舒适和可控的清理。现在恐慌就像其他语言中的raise()一样。在函数recover()的帮助下,你有机会在调用堆栈上升时发现这种恐慌。这种方式几乎与try / catch类似。但是后者在块上工作恐慌/恢复工作在功能级别。

Rob Pike关于这个解决方案的原因:“我们不想鼓励混淆Java等语言中出现的错误和异常。”为了避免运行时错误,应该尽一切努力避免运行时错误,在确定后提供正确的错误返回值,并且只有在没有其他方法时才使用恐慌/恢复,而不是拥有大量不同的异常。

答案 3 :(得分:6)

我认为我们都同意std::shared_ptr<>panicthrowrecovercatchdefer

差异似乎是finally进入recover。回到传统术语,它可以让您准确地确定defer您想要打扰finally任何内容的哪一点,或者根本不需要。

答案 4 :(得分:2)

我认为Panic与throw相同,Recover与catch相同。不同之处在于推迟。在开始时,我认为延迟与最终相同,但后来,我发现延迟比最终更灵活。延迟可以放在你的函数的任何范围内,并记住当时参数的值,也可以改变返回的返回值,恐慌可以在延迟之后的任何地方。但由于缺少try块,除非返回整个函数,否则我们无法处理“异常”。我不认为这是一个劣势,也许GO想让你的方法只做一件事,任何异常都应该让这件事情无法继续下去。 因为恐慌必须在延迟之后,所以你必须在使用之前处理它的“例外”。

这只是对自己的理解。