英文:
Exception handling in Google Go language
问题
我在想...我之前读过关于Go的一些东西,然后我尝试用它来编写一些程序。它似乎非常有趣。但是我遇到了在这种语言中处理“异常”的问题。我已经阅读了他们的方法,它似乎是合理的。我想知道标准异常处理方法与Go的风格相比有什么优势?有什么利弊?
编辑 直截了当地说:我不想就异常问题展开任何战争。我只是想知道这种处理错误的方式是否有任何优势?这种方式相对于标准异常的实际优势是什么?是否值得思考?
英文:
I am wondering... I have read about Go some time ago and I tried to program something in it. I seems quite interesting. But I have reached handling "exceptions" in this language. I have read about their approach and it seems reasonable. I would like to know what are the advantages of the standard exceptional approach over the Go's style? What are the pros and cons?
Edit To be straight: I do not want to make any holy war about exceptions. I just wonder if this style of handling errors has any advantages? What are actual advantages of this style over standard exceptions? Is it worth wondering at all?
答案1
得分: 58
panic/recover是try/catch异常的道德等价物。它们之间有表面上的差异(语法)和微妙但重要的使用差异。
关于异常问题的最好解释是“更清洁、更优雅、错误”的文章,这是关于异常与返回错误代码的优缺点的概述。
Go的设计者决定通过从函数返回错误代码来处理错误是Go的惯用方式,语言支持多返回值,使其在语法上更容易。虽然提供了panic/recover,但差异不在于功能,而在于使用目的。
其他语言暴露异常并推广其使用,在实践中它们经常被使用(有时甚至被滥用)。
Go不鼓励使用panic/recover。你可以使用它,但只能在非常有限的情况下使用。
如果你看一下Go自己的标准库,大多数panic的使用是用于标识致命错误,表示库代码中的内部错误(即错误)或者使用错误的数据调用库(例如将非JSON数据传递给JSON解码函数)。
但正如你链接的文章指出的:“Go库的约定是,即使一个包在内部使用panic,其外部API仍然提供明确的错误返回值。”
这与C#、Java、Python或C++等语言不同,这些语言的许多标准库代码可以抛出异常来表示错误。这些语言希望你使用异常。Go不鼓励使用panic/recover。
总结一下:
- Go的惯用风格是使用错误代码告诉调用者错误信息
- 只在以下罕见情况下使用panic/recover:
- 在遇到内部不一致性(表示代码中的错误)时“崩溃”程序。它基本上是一个调试辅助工具。
- 如果它极大地简化了代码的错误处理(但如果代码将被他人使用,永远不要将这些panic暴露给调用者)
实际上,重要的是使用语言的惯用风格。在Go中,这意味着返回错误代码并避免使用panic/recover。在C#中,这意味着使用异常来表示某些错误。
英文:
panic/recover is moral equivalent of try/catch exceptions. There is superficial difference (syntax) and a subtle, but important, difference of intended use.
The best explanations of problems with exceptions in general is "Cleaner, more elegant, wrong" and that's a good overview of pros/cons of exceptions vs. returning error codes.
Go designers decided that error handling by returning error codes from functions is the idiomatic Go way and the language supports multiple return values to make it syntactically easy. While panic/recover is provided, the difference is not of functionality but intended use.
Other languages exposing exceptions promote their use and in practice they are used frequently (sometimes even misused).
Go discourages the use of panic/recover. You can do it but you're only supposed to do it in very limited scenarios.
If you look at Go's own standard library, most uses of panic are for signaling fatal errors, indicating either an internal error (i.e. bug) in the library code or calling the library with wrong data (e.g. passing non-json data to json decoding functions).
But as the article you linked to points out: "The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values."
This is different from languages like C#, Java, Python or C++, where a lot of standard library code can throw exceptions to signal errors. Those languages want you to use exceptions. Go discourages the use of panic/recover.
To summarize:
- idiomatic Go style is to use error codes to tell the caller about errors
- use panic/recover only in rare cases:
- to "crash" your program when encountering internal inconsistency indicating bugs in your code. It's basically a debugging aid.
- if it dramatically simplifies error handling in your code (but if the code is to be used by others, never expose such panics to callers)
In practice the important thing is to use language's idiomatic style. In Go that's returning error codes and avoiding panic/recover. In C# that's using exceptions to signal some of the errors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论