Go语言中的恢复恐慌(panic recover)与其他语言中的try catch的比较

huangapple go评论93阅读模式
英文:

Panic recover in Go v.s. try catch in other languages

问题

我刚刚阅读了关于Go语言中的Panic/Recover的这篇文章,我不太清楚这与其他主流语言中的try/catch有什么不同。

英文:

I've just read this post about Panic/Recover in Go and I'm not clear on how this differs from try/catch in other mainstream languages.

答案1

得分: 31

Panic/Recover是函数作用域的。这就像是说在每个函数中只允许有一个try/catch块,并且try块必须覆盖整个函数。这使得在使用Panic/Recover时,与Java/Python/C#等语言使用异常的方式非常麻烦。这是有意为之的。
这也鼓励人们以设计时的方式使用Panic/Recover。你应该从panic()中恢复(recover()),然后向调用者返回一个错误值。

英文:

Panic/Recover are function scoped. It's like saying that you're only allowed one try/catch block in each function and the try has to cover the whole function. This makes it really annoying to use Panic/Recover in the same way that java/python/c# etc. use exceptions. This is intentional.
This also encourages people to use Panic/Recover in the way that it was designed to be used. You're supposed to recover() from a panic() and then return an error value to the caller.

答案2

得分: 24

我一直在思考如何最好地回答这个问题,所以一直在看着它。最简单的方法是指出 panic/recover 的习惯用法与其他语言中的 try/catch 和异常的区别,或者这些习语背后的概念(可以简单地总结为“异常应该只在真正异常的情况下发生”)。

但是关于它们之间的 实际 差异是什么?我会尽力概括。

try/catch 块相比,一个主要的区别是控制流的方式。在典型的 try/catch 场景中,除非它传播错误,否则在 catch 块之后的代码将会运行。而 panic/recover 不是这样的。panic 中止当前函数并开始展开堆栈,在遇到它们时运行延迟函数(recover 唯一有用的地方)。

实际上,我会更进一步地说:panic/recover 在某种意义上几乎与 try/catch 没有任何相似之处,因为 try 和 catch 是(或者至少表现得像)控制结构,而 panic/recover 不是。

这实际上源于 recover 是围绕 defer 机制构建的事实,而(据我所知)defer 是 Go 中一个相当独特的概念。

当然还有更多,如果我能更好地表达我的想法,我会补充的。

英文:

I keep looking at this question trying to think of the best way to answer it. It's easiest to just point to the idiomatic uses for panic/recover as opposed to try/catch &| exceptions in other languages, or the concepts behind those idioms (which can be basically summed up as "exceptions should only occur in truly exceptional circumstances")

But as to what the actual difference is between them? I'll try to summarize as best I can.

One of the main differences compared to try/catch blocks is the way control flows. In a typical try/catch scenario, the code after the catch block will run unless it propagates the error. This is not so with panic/recover. A panic aborts the current function and begins to unwind the stack, running deferred functions (the only place recover does anything) as it encounters them.

Really I'd take that even further: panic/recover is almost nothing like try/catch in the sense that try and catch are (or at least act like) control structures, and panic/recover are not.

This really stems out of the fact that recover is built around the defer mechanism, which (as far as I can tell) is a fairly unique concept in Go.

There are certainly more, which I'll add if I can actuate my thoughts a bit better.

答案3

得分: 16

我认为我们都同意panicthrowrecovercatchdeferfinally

最大的区别似乎是recover放在defer内部。回到传统的术语,它让你决定在finally的哪个点上你想要打扰catch任何东西,或者根本不打扰。

英文:

I think we all agree that panic is throw, recover is catch, and defer is finally.

The big difference seems that recover goes inside defer. Going back to traditional terms, it lets you decide exactly at which point of your finally you want to bother catching anything, or not at all.

答案4

得分: 10

defer是一种机制,不仅用于处理错误,还用于进行舒适和可控的清理工作。现在,panic的工作方式类似于其他语言中的raise()。借助函数recover()的帮助,您有机会在它沿着调用堆栈上升时捕获这个panic。这种方式几乎类似于try/catch。但是,后者适用于块级别,而panic/recover适用于函数级别。

Rob Pike关于这种解决方案的原因:“我们不希望鼓励像Java这样的语言中发生的错误和异常的混淆。”。与其拥有大量不同的异常和更多的用法,不如尽一切努力避免运行时错误,在确定后提供适当的错误返回值,并仅在没有其他方法时使用panic/recover。

英文:

defer is a mechanism not only for handling errors but also for doing a comfortable and controlled cleanup. Now panic works like raise() in other languages. With the help of the function recover() you've got the chance to catch this panic while it goes up the call stack. This way it's almost similar to try/catch. But while the latter works on blocks panic/recover works on function level.

Rob Pike about the reason for this solution: "We don't want to encourage the conflation of errors and exceptions that occur in languages such as Java.". Instead of having a large number of different exceptions with an even larger number of usages one should do everything to avoid runtime errors, deliver proper error return values after determination and use panic/recover only if there's no other way.

答案5

得分: 4

我认为Panic和throw是相同的,Recover和catch是相同的。区别在于defer。一开始,我认为defer和finally是相同的,但后来我发现defer比finally更灵活。defer可以放置在函数的任何作用域,并记住该时刻的参数值,还可以更改返回的返回值,然后在defer之后的任何位置都可以发生panic。但由于缺少try块,除非整个函数返回,否则我们无法处理“异常”。我不认为这是一个缺点,也许GO希望使您的方法只做一件事,任何异常都应该使这件事无法继续进行。
而且由于panic必须在defer之后,这使得您必须在使用之前处理其“异常”。

这只是我个人的理解。

英文:

I think the Panic is the same as throw,Recover is the same as catch. The difference is at defer. At the begin, I think defer is the same as finally,but later, I find defer is more flexible than finally. defer can be place at any scope of your function and remember the value of parameter at that moment and also can change the returned return value,the the panic can be at any where after defer. but because the missing of block of try, we can't process the "exception" unless the whole function returned. I don't think this is a disadvantage,maybe GO want to make your method only do one thing, any exception should make this thing can't go on.
and since panic must after defer, it make you must process its "exception" before use it.

this is just understanding of myself .

答案6

得分: 0

"go"与其他语言不同,它是一种并发语言,意味着程序的部分可以并行运行。这意味着如果设计者想要有类似于catch/throw的机制,这个机制必须在这个上下文中被精心重新定义。这解释了这两种机制之间的差异。

英文:

"go" is unlike other languages a concurrent language, meaning that parts of the program runs in parallel. This means that if the designers want to have a similar mechanism as catch/throw , the mechanism has to meticulously redefined in this context. That explains the differences between the two mechanisms.

huangapple
  • 本文由 发表于 2010年8月5日 17:29:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/3413389.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定