Go中的恐慌恢复与其他语言的尝试捕获

Mot*_*tti 36 error-handling exception go

我刚读过这篇关于恐慌/恢复的帖子,我不清楚它与其他主流语言中的try/catch有何不同.

Jes*_*sta 22

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


cth*_*m06 20

我一直在考虑这个问题,试图想出最好的方法来回答它.与try/catch&| 相比,最容易指向恐慌/恢复的惯用用法 其他语言中的例外,或这些习语背后的概念(基本上可以概括为"例外应该只在真正特殊情况下发生")

但至于它们之间的实际差异是什么?我会尽力总结一下.

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

真的,我会更进一步:恐慌/恢复几乎不像try/catch,因为try和catch是(或者至少就像)控制结构,而恐慌/恢复则不然.

这实际上源于这样一个事实,即恢复是围绕延迟机制构建的,据我所知,这是一个相当独特的概念.

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

  • 这是我的看法:panic 大致类似于 throw。带有recover 语句的defer 大致类似于catch。与 try 块最接近的类似物是当前函数的主体。 (5认同)
  • 谢谢,BTW,"defer"与D的"范围"非常相似 (2认同)
  • 这篇文章非常教条。“恐慌中止当前函数并开始展开堆栈”也是异常的作用。对于同一问题,panic/recover 和 throw/catch 在语义上是不同的解决方案 (2认同)
  • @Espen 十年后,我确信我会以不同的方式解释(并且希望更好),但该声明的上下文是在恐慌/恢复与抛出/捕获的背景下​​,而不仅仅是恐慌与抛出。是的,panic 和 throw 都开始展开堆栈,但是在 go 中不可能恢复当前函数的执行,而 catch 确实允许您恢复当前函数。 (2认同)

the*_*mue 9

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

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


Eke*_*voo 6

我想我们都同意这panicthrow,recover现在catchdeferfinally.

recover内部存在巨大差异defer.回到传统术语,它可以让你准确地决定finally你想要打扰catch任何东西,或者根本不想.