zla*_*ski 11 error-handling exception-handling go
为什么Go最终会采用恐慌/恢复的异常处理,当语言如此惯用并且是错误代码的强烈提倡者时?Go的设计者有哪些场景不会被错误代码处理并且需要恐慌/恢复?
我理解约定说限制恐慌/恢复,但运行时是否也限制它们不能用作C++中的常规throw/catch?
icz*_*cza 12
一些历史:
在Go的早期(版本1.0之前),没有recover().调用panic()将终止一个应用程序而无法阻止它.
我找到了导致添加的原始讨论recover(),你可以在golang-nuts讨论论坛上阅读:
请注意:讨论的历史可以追溯到2010年3月25日,这是非常令人精疲力尽的(150页至6页).
最终它被添加到2010-03-30:
此版本包含三种语言更改:
- 功能
panic和recover,用于报告和从故障中恢复,已添加到规范:
http://golang.org/doc/go_spec.html#Handling_panics
在相关的变化,panicln时代已经过去了,panic现在是一个单参数函数.恐慌和恢复被gc编译器识别,但新行为尚未实现.
多返回值和约定提供了一种更简洁的方法来处理Go中的错误.
然而,这并不意味着在某些(罕见)情况下恐慌恢复无效.
Go还有一些内置功能,可以在真正特殊的条件下发出信号并从中恢复.恢复机制仅作为函数状态在错误发生后被拆除的一部分执行,这足以处理灾难但不需要额外的控制结构,并且如果使用得当,可以产生干净的错误处理代码.
以下是关于何时/如何有用的"现实生活"示例:引用博客文章Defer,Panic and Recover:
有关恐慌和恢复的真实示例,请参阅Go标准库中的json包.它使用一组递归函数对JSON编码的数据进行解码.当遇到格式错误的JSON时,解析器调用panic将堆栈展开到顶级函数调用,该函数调用从恐慌中恢复并返回适当的错误值(请参阅解码中的decodeState类型的'error'和'unmarshal'方法).go).
另一个例子是当你编写调用用户提供的函数的代码(例如包)时.你不能相信它提供的功能,它不会恐慌.一种方法是不处理它(让恐慌结束),或者你可以选择通过从那些恐慌中恢复来"保护"你的代码.一个很好的例子是标准库中提供的http服务器:你是提供服务器将调用的函数(处理程序或处理程序函数)的那个,如果你的处理程序恐慌,服务器将从那些恐慌中恢复而不是让你的完整申请模具.
你应该如何使用它们:
Go库中的约定是即使包在内部使用panic,其外部API仍然会显示明确的错误返回值.
相关和有用的读物:
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