dongye8110 2016-02-15 14:54
浏览 34

为什么Go除了错误处理外还会增加恐慌并恢复? [关闭]

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++?

  • 写回答

4条回答 默认 最新

  • ds1379551 2016-02-15 15:22
    关注

    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

    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100