为什么除了错误处理之外添加恐慌和恢复? [英] Why did Go add panic and recover in addition to error handling?

查看:137
本文介绍了为什么除了错误处理之外添加恐慌和恢复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Go最终采用异常处理的恐慌/恢复,当语言如此惯用,强烈的提倡错误代码? Go想象的设计者不会通过错误代码处理哪些场景,并且需要进行紧急/恢复?



我理解约定说限制panic / recover,但是运行时也限制了在C ++中不能将它们作为一般的throw / catch来使用?

解决方案

strong>



在Go的早期(1.0版之前)没有 recover()。调用 panic()将终止应用程序,没有任何方法可以阻止。



我发现原来的讨论导致添加 recover(),您可以在golang-nuts讨论区上阅读:



针对类似异常的提案机制



请注意:讨论可以追溯到2010年3月25日,这是非常耗尽和长久的(150篇帖子通过6页)。



最终,它已添加到 2010-03-30


此版本包含三种语言更改:


  1. 函数 panic recover ,旨在从
    失败报告和恢复,已添加到规范中:

    http://golang.org/doc/go_spec.html#Handling_panics

    在相关更改中, panicln 已经消失,而 panic 现在是一个单一的,参数
    函数。紧急和恢复被gc编译器识别,但新的
    行为尚未实现。


多返回值和约定提供了一种更清晰的方式来处理Go中的错误。



但这并不意味着在某些(罕见)情况下,恐慌恢复无效。



从官方常见问题:为什么Go没有例外?


还有几个内置功能,从真正特殊的条件发出信号和恢复。恢复机制仅作为函数的状态的一部分执行,在错误之后被拆除,这足以处理灾难,但不需要额外的控制结构,并且在使用得当时可以导致干净的错误处理代码。


这是一个现实生活的例子,用于何时/如何有用:引用博客文章


对于 panic 恢复的现实世界示例,请参阅 json包。它使用一组递归函数解码JSON编码的数据。当遇到格式错误的JSON时,解析器调用panic将堆栈解压缩到顶层函数调用,该函数调用从紧急状态恢复,并返回一个适当的错误值(请参阅error和unmarshal中的decodeState类型的方法, a href =http://golang.org/src/pkg/encoding/json/decode.go =nofollow> decode.go )。




另一个例子是当你编写一个调用用户提供的函数的代码(例如包)时。你不能信任所提供的功能,它不会惊慌。一种方法是不要处理(让恐慌发生),或者您可以选择通过从这些恐慌中恢复来保护您的代码。一个很好的例子是标准库中提供的 http服务器:您是提供的服务器将调用的功能(处理程序处理函数),如果您的处理程序恐慌,服务器将从这些恐慌中恢复,不让您的完整应用程序死亡。 / p>

应该如何使用它们:


Go库中的约定是即使一个软件包在内部使用panic,它的外部API仍然会提供明确的错误返回值。


相关和有用的读数:



http://blog.golang.org/延迟恐慌和恢复



http://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right



https://golang.org/doc/faq#exceptions



http://evanfarrer.blogspot.co.uk/2012/05/go-programming-language-has-exceptions.html


Why did Go end up adopting exception handling with panic/recover, when the language is so idiomatic and a strong advocate of error codes? What scenarios did the designers of Go envision not handled by error codes and necessitate panic/recover?

I understand convention says limit panic/recover, but does the runtime also limit them in ways that they can't be used as general throw/catch in C++?

解决方案

Some history:

In the early days of Go (before version 1.0) there was no recover(). A call to panic() would terminate an application without any way to stop that.

I've found the original discussion that led to adding recover(), you can read it on the golang-nuts discussion forum:

Proposal for an exception-like mechanism

Beware: the discussion dates back to March, 25, 2010, and it is quite exhausting and long (150 posts through 6 pages).

Eventually it was added on 2010-03-30:

This release contains three language changes:

  1. The functions panic and recover, intended for reporting and recovering from failure, have been added to the spec:
    http://golang.org/doc/go_spec.html#Handling_panics
    In a related change, panicln is gone, and panic is now a single-argument function. Panic and recover are recognized by the gc compilers but the new behavior is not yet implemented.


Multi-return values and conventions provide a cleaner way to handle errors in Go.

That does not mean however that in some (rare) cases the panic-recover is not useful.

Quoting from the official FAQ: Why does Go not have exceptions?

Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code.

Here is a "real-life" example for when/how it can be useful: quoting from blog post Defer, Panic and Recover:

For a real-world example of panic and recover, see the json package from the Go standard library. It decodes JSON-encoded data with a set of recursive functions. When malformed JSON is encountered, the parser calls panic to unwind the stack to the top-level function call, which recovers from the panic and returns an appropriate error value (see the 'error' and 'unmarshal' methods of the decodeState type in decode.go).

Another example is when you write code (e.g. package) which calls a user-supplied function. You can't trust the provided function that it won't panic. One way is not to deal with it (let the panic wind up), or you may choose to "protect" your code by recovering from those panics. A good example of this is the http server provided in the standard library: you are the one providing functions that the server will call (the handlers or handler functions), and if your handlers panic, the server will recover from those panics and not let your complete application die.

How you should use them:

The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.

Related and useful readings:

http://blog.golang.org/defer-panic-and-recover

http://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right

https://golang.org/doc/faq#exceptions

http://evanfarrer.blogspot.co.uk/2012/05/go-programming-language-has-exceptions.html

这篇关于为什么除了错误处理之外添加恐慌和恢复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆