Go c语言消息机制的错误处理机制是一个优秀的设计吗

但是如果使用改进的健壮性和错误处理机制,只需三行代码即可完成同一任务。
But the same task, with improved robustness and error handling, can be accomplished in three lines of code.
这样的代码更易于阅读、维护,而且我要说,甚至要鼓励您添加错误处理机制,它通常都能带来好处。
The code is easier to read, easier to maintain, and (I would say) even encourages you to add error handling, which is always a benefit.
一种成熟的错误处理机制,包括在出现工作流程“回滚”到特定的点这种情况时要处理的补偿事务。
A sophisticated error handling mechanism that includes handling of compensating transactions in cases where a workflow must be "rolled back" to a specific point.
您了解了从SCA和非SCA组件访问服务的各种方式,还了解了各种错误处理机制、异步编程模型和各种异步调用。
You've seen various ways to access services from both SCA and non-SCA Java components -- and the various error handling mechanismsm asynchronous programming model and various asynchronous calls.
提供了更好的错误处理机制,提高了问题的确定和解决能力。
There is better error handling for improved problem determination and resolution.
更确切地说,在该标记的主体内容中产生的任何异常都会被捕获并被忽略(即,不会调用标准的JSP错误处理机制)。
More specifically, any exceptions raised within the body content of this tag will be caught and ignored (that is, the standard JSP error-handling mechanism will not be invoked).
值得注意的是,为了创建一个集中式的、更简洁的错误处理机制,errorPage.jsp被调用来处理任何错误。
It is worth noting that errorPage.jsp is called to handle any error, in order to create a centralized and cleaner error-handling mechanism.
新的内建函数recover在错误处理机制上对panic和defer进行了补充。
The new built-in function recover complements panic and defer as an error handling mechanism. [blog, spec]
全局错误处理:针对Flash运行时进行应用开发的开发者最希望加入的特性就是全局错误处理机制。
Global error handling: The most requested feature by those developing applications for the Flash runtime is a mechanism for global error handing.
在 图1 中可以看到,Java运行时环境(JRE)包含用Java实现的错误处理机制。
If you look at the diagram in
Figure 1, you see that the Java runtime environment (JRE) contains the error-handling mechanisms in Java.
如果必要,将一个活动及其附加错误处理机制收集到一个子流程中,以保持父流程 “整洁”。
If necessary, collect an activity and its attached error handling into a sub process to keep the parent process "cleaner."
理由在于:一个有错误但带有优秀的错误处理机制的应用程序,比近乎完美但其错误处理机制却不友好的应用程序,更能赢得最终用户的欢心。
This is the reason: a faulty application with good error-handling seems to leave end-users with more satisfaction and comfort than one that's nearly perfect, but has a hostile error-handler.
为了建立强大的错误处理机制,需要采用分层的方法
To build strong error handling, you need a layered approach
应用程序中内建了详细的错误处理机制
Detailed error handling built into the application
主要讨论了高阻自动测量系统软件的状态机设计、组件的可重用性和错误处理机制实现。
The paper discussed the design of state machines, the reusability considerations and the error handling mechanism in detail.
这个预编译器改进了C语言错误处理机制,提高了软件开发效率。
The precompiler improved improves the mechanism of handling errors in C language, and increased increases software development efficiency.
在托管和非托管对象模型之间,数据类型、方法签名和错误处理机制都存在差异。
Data types, method signatures, and error-handling mechanisms vary between managed and unmanaged object models.
用户在网络层上并没有真正的控制权,所以它们不可能用更好的路由器或者在数据链路层上用更多的错误处理机制来解决服务太差的问题。
The users have no real control over the network layer, so they cannot solve the problem of poor service by using better routers or putting more error handling in the data link layer.
让我们来看看在Java 中导致错误的调用序列,并研究在通常的Java应用程序中处理错误的机制。
Let's look at the sequence in Java that leads up to an error and examine the mechanics of how an error is handled in a typical Java application.
可以通过异步处理和错误恢复机制保证得到应答。
Answers are guaranteed with exception-handling and error-recovery mechanisms.
由于业务之间的相互关系没有被定义、业务数据不完全、以及不具备错误处理或者补偿机制,所以BPEL1.1规范只包含了一个局部解决方案。
The BPEL 1.1 spec contains only a partial solution, because correlation sets aren't defined, the business data is incomplete, and there is no fault handling or compensation.
XPath元素和属性名称中的简单错误也无法被XSLT处理器的错误检查机制检测到。
Simple errors in the names of elements and attributes in XPath expressions go undetected by the error-checking mechanisms of your XSLT processor.
<p:try>:提供一种尝试/捕获机制来处理动态错误
<p:try>: Provides a try/catch mechanism to handle dynamic errors
一种被广泛采用的失败处理机制是异常处理,包括捕获并记录错误,以及在失败发生时选择一个备选执行路径。
A widely adopted mechanism for dealing with failures is exception handling, encompassing both capturing and logging the error and choosing an alternative execution path in the case of failures.
错误处理不包括遇错重新传输机制,因为该机制会产生较高的端对端延时和较大的抖动。
Again, the error handling does not include retransmission because this mechanism would introduce high end- to -end delays and strong jitter.
异常处理机制是一种运行时错误通知机制,将程序的正常控制代码和错误处理代码分离。
Exception handling is a runtime-error notifying mechanism. It separates the error handling code from normal code and makes software do its utmost to run on the normal state.
本文提出一种将基于转换的错误驱动的学习机制用于冠词处理的策略,初步实验显示,这种方法可以有效地提高机器译文中冠词使用的准确率。
In this paper, we proposal a strategy for article selection which based the Transformation Based Error Driven Learning Algorithm, an initial experimental result shows the…
架构机制的例子包括持续性、远程功能、有效性和错误处理,及许多其他内容。
Examples of architectural mechanisms include persistency, remote-ability, validation and error handling, and many others.
以一种可扩展的机制在捕捉组件中执行定制的检验,并处理检验过程中遇到的错误
An extensible mechanism for executing custom validation in the capture component and handling failures of such validation
以一种可扩展的机制在捕捉组件中执行定制的检验,并处理检验过程中遇到的错误
An extensible mechanism for executing custom validation in the capture component and handling failures of such validation
$firstVoiceSent
- 来自原声例句
请问您想要如何调整此模块?
感谢您的反馈,我们会尽快进行适当修改!
请问您想要如何调整此模块?
感谢您的反馈,我们会尽快进行适当修改!Go 语言的错误处理机制引发争议 - 开源中国社区
当前访客身份:游客 [
当前位置:
最近,有关Go语言的错误处理机制在社区中展开了讨论,有人认为冗长重复的错误处理格式像是回到了上世纪七十年代,而Go语言的开发者给予了反驳。
Go语言的错误处理机制可以从说起:
在C语言当中常见的做法是保留一个返回值来表示错误(比如,read()返回0),或 者保留返回值来通知状态,并将传递存储结果的内存地址的指针。这容易产生了不安全的编程实践,因此在像Go语言这样有良好管理的语言中是不可行的。认识到 这一问题的影响已超出了函数结果与错误通讯的简单需求的范畴,Go的作者们在语言中内建了函数返回多个值的能力。作为例子,这个函数将返回整数除法的两个部分:
func divide(a, b int) (int, int) {
quotient := a / b
remainder := a % b
return quotient, remainder
多返回值的出现促进了&comma-ok&的模式。有可能失败的函数可以返回第二个布尔结果来表示成功。作为替代,也可以返回一个错误对象,因此像下面这样的代码也就不见怪了:
if result, ok := moreMagic(); ok {
/* Do something with result */
除此之外,Go语言还提供了Panic/Recover机制,陈皓在“”中有比较详细的描述:
对于不可恢复的错误,Go提供了一个内建的panic函数,它将创建一个运行时错误并使程序停止(相当暴力)。该函数接收一个任意类型(往往是字符串)作为程序死亡时要打印的东西。当编译器在函数的结尾处检查到一个panic时,就会停止进行常规的return语句检查。
下面的仅仅是一个示例。实际的库函数应避免panic。如果问题可以容忍,最好是让事情继续下去而不是终止整个程序。
var user = os.Getenv(&USER&)
func init() {
if user == && {
panic(&no value for $USER&)
当panic被调用时,它将立即停止当前函数的执行并开始逐级解开函数堆栈,同时运行所有被defer的函数。如果这种解开达到堆栈的顶端,程序就 死亡了。但是,也可以使用内建的recover函数来重新获得Go程的控制权并恢复正常的执行。 对recover的调用会通知解开堆栈并返回传递到panic的参量。由于仅在解开期间运行的代码处在被defer的函数之内,recover仅在被延期 的函数内部才是有用的。
你可以简单地理解为recover就是用来捕捉Painc的,防止程序一下子就挂掉了。
Python和Go语言的实践者Yuval Greenfield在“”的博文中批评了Go语言的错误处理机制。他首先引用了Go语言的设计者对错误处理机制的看法:
在Go语言中,错误处理非常重要。语言的设计和规范鼓励开发人员显式地检查错误(与其他语言抛出异常然后catch住是不同的)。这种机制某种程度上使得Go语言的代码冗长重复,但是幸运的是你可以利用一些技巧来把冗长的代码最小化。
Yuval表示这点他无法忍受,每一次函数的调用都需要if语句来判断是否出现错误,他引用了一段官方的所谓最小化代码量的错误处理示例:
if err := datastore.Get(c, key, record); err != nil {
return &appError{err, &Record not found&, 404}
if err := viewTemplate.Execute(w, record); err != nil {
return &appError{err, &Can't display record&, 500}
Yuval说,这就是在Go语言中调用函数的正确处理方式,甚至连Println的调用都要这样做。如果不这么做会怎样呢?Go语言并没有坚持要采 用这种冗长的错误机制。它也允许忽略这些函数调用错误。但是这样做很危险。在下面的例子中,如果第一个Get函数错误,那么程序继续调用第二个函数!这是 非常恐怖的事情。
func main() {
http.Get(&http://www.nuke.gov/seal_presidential_bunker&)
http.Get(&http://www.nuke.gov/trigger_doomsday_device&)
理论上,我们要求开发人员决不能忽略返回的错误。而实际上,只有在一些关键性的错误上面处理才是必要的。
关于panic/recover机制,Yuval认为也不够出色,因为连Go的标准库都不怎么用这种机制:为什么索引溢出的数组要比错误格式的字符 串或者失败的网络连接更需要panic呢?Go语言希望能够完全避免异常,但实际上不能,总有一些异常会在某处发生,让开发人员在错误出现时感到困惑。
针对Yuval的批评,Go的开发者Russ Cox做出了:
在Go语言中,规定的方式是,函数返回错误信息。如果一个文件并不存在,op.Open函数会返回一个错误信息。如果你向你一个中断了的网络连接里 写数据,net.Conn里的Write方法会返回一个错误。这种状况在这种程序中是可以预料到的。这种操作就是容易失败,你知道程序会如何运行,因为 API的设计者通过内置了一种错误情况的结果而让这一切显得很清楚。
从另一方面讲,有些操作基本上不会出错,所处的环境根本不可能给你提示错误信息,不可能控制错误。这才是让人痛苦的地方。典型的例子;一个程序执行 x[j],j值超出数组边界,这才痛苦。像这样预料之外的麻烦在程序中是一个严重的bug,一般会弄死程序的运行。不幸的是,由于这种情况的存在,我们很 难写出健壮的,具有自我防御的服务器——例如,可以应付偶然出现的有bug的HTTP请求处理器时,不影响其他服务的启动和运行。为解决这个问题,我们引 入了恢复机制,它能让一个go例程从错误中恢复,服务余下设定的调用。然而,代价是,至少会丢失一个调用。这是特意而为之的。引用邮件中的原话:“这种设 计不同于常见的异常控制结构,这是一个认真思考后的决定。我们不希望像java语言里那样把错误和异常混为一谈。”
Russ Cox针对“为什么数组越界造成的麻烦会比错误的网址或断掉的网络引出的问题要大?”这个问题给出了自己的答案:
我们没有一种内联并行的方法来报告在执行x[j]期间产生的错误,但我们有内联并行的方法报告由错误网址或网络问题造成的错误。
使用Go语言中的错误返回模式的规则很简单:如果你的函数在某种情况下很容易出错,那它就应该返回错误。当我调用其它的程序库时,如果它是这样写的,那我不必担心那些错误的产生,除非有真正异常的状况,我根本没有想到需要处理它们。
最后,Russ Cox指出Go语言是为大型软件设计的:
我们都喜欢程序简洁清晰,但对于一个由很多程序员一起开发的大型软件,维护成本的增加很难让程序简洁。异常捕捉模式的错误处理方式的一个很有吸引力 的特点是,它非常适合小程序。但对于大型程序库,如果对于一些普通操作,你都需要考虑每行代码是否会抛出异常、是否有必要捕捉处理,这对于开发效率和程序 员的时间来说都是非常严重的拖累。我自己做开发大型Python软件时感受到了这个问题。Go语言的返回错误方式,不可否认,对于调用者不是很方便,但这 样做会让程序中可能会出错的地方显的很明显。对于小程序来说,你可能只想打印出错误,退出程序。对于一些很精密的程序,根据异常的不同,来源的不同,程序 会做出不同的反应,这很常见,这种情况中,try + catch的方式相对于错误返回模式显得冗长。当然,Python里的一个10行的代码放到Go语言里很可能会更冗长。毕竟,Go语言主要不是针对10行 规模的程序的。
热情的技术探索者,资深软件工程师,InfoQ编辑,从事企业级Web应用的相关工作,关注性能优化、Web技术、浏览器等领域。
共有32个评论
<span class="a_vote_num" id="a_vote_num_
非常不看好Go语言,理由:没有C++的基础好,没有Cython方便,没有C通用。也没有Java小白多。
<span class="a_vote_num" id="a_vote_num_
go语言的设计者不懂得支持事务的应用程序设计,因此对“发生错误,然后丢掉状态”极度紧张,认为这总是错误的。也不懂得多角度的去看待“异常”(辩证地)。一个网络异常,对于框架或者基础设施而言,他可能是必须处理的“业务”,而对于建模现实业务的代码而言,则褪变成了真正的“异常”,属于部署方面的问题,与被太阳黑子翻转的内存bit是同一类的,这些异常应该作为一个“方面”进行解决,而不是处处交杂在业务代码中。
go的两种错误处理机制,不能够方便地在两种视角上进行转换,并且相对于与标准的异常机制而言,增加了语言的复杂性。
go最初鼓吹是正交的,但go是我所见的最不正交的语言。
go之所以提出panic,其实是后来一种不自信的补救。
--- 共有 4 条评论 ---
果然 引发争议
看来要系统学习下错误处理的东西
(4年前)&nbsp&
你所说的增加语言复杂性完全是扯淡,几乎没有一本书告诉你如何正确使用异常处理,虽然举了一大堆例子,但是总是告诉你要合理使用不可滥用(什么叫合理什么叫滥用根本没人说过)完全就是学院派的那种理想主义,太阳黑子如果引发问题的话你就是用了异常处理也捕获不到错误,硬件都出错了软件还不出错?现在异常嵌套异常的更恶心,大家还要知道异常抛出格式和类型。
(4年前)&nbsp&
如果JVM出错了a = 100;这样一般看来根本不会出错的语句也会崩溃的.毕竟他需要解释执行虚拟机无法保证所有代码都解释执行成功,go是编译型语言.除非CPU有问题否则根本不会出现mov eax, 100出错的事情.再说现在那些玩溢出的都是在覆盖异常返回点。自己抛自己接有意思么?效率还低。更无法跨语言跨服务跨平台。最后还是回到RPC上。RPC也是返回值处理方式。
(4年前)&nbsp&
开发go语言那两位写代码的时间比你年龄都大,取得的成就也比你认识(也认识你)的所有程序员加起来都大。人家不懂事务处理?再说异常是怎么返回信息的?不也是抛出一个异常里面夹杂着返回信息么。在其他帖子也说过了。虚拟机,动态语言都是不可预料错误的。所以必须用异常。
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
&&&&&& 暂时没看懂, 如果忽略错误且错误真发生的时候会导致panic(). & 那的确是非常糟糕的设计.&& 比如说C++的异常说明 就是非常糟糕的, 因为一旦不符合异常说明 就会调用panic(). 这简直是恐怖主义.
--- 共有 1 条评论 ---
异常处理不去捕获和操作都会引发崩溃的事情。而且go没有提倡你使用异常处理,甚至搞出多个返回值来帮你处理这些问题。go没必要搞异常处理。直接返回值就足够了,返回值不if不会崩溃,异常不处理那就崩溃到姥姥家了。C++还鼓励用异常我是难以理解,底层代码都崩溃了你指望谁给你擦屁股呢?
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
go 语言 接近c,学学去。
<span class="a_vote_num" id="a_vote_num_
我也非常不习惯go语言的异常处理机制。
<span class="a_vote_num" id="a_vote_num_
有人能说明一下异常和错误有什么区别么?程序什么时候要抛出异常,什么时候返回error。
panic/recover机制和throw/catch 有什么区别。throw不是最后也终止程序,catch可以让throw终止程序么?panic/recover不是和这个很像??有什么区别
--- 共有 14 条评论 ---
我感觉像 法律上的 责任认定。。。
(4年前)&nbsp&
: 在函数调用的最顶层捕获异常,应该不会崩溃的。
(4年前)&nbsp&
: 你可以调试找出错误点直接处理错误返回值就好了。你不处理也不会造成服务崩溃。只要有一个if处理了这个返回值,就可以知道运行出错了。然后做相应的处理即可。函数执行出错是可以被允许的没有人说一个函数执行肯定会绝对正确,但是异常处理要是有一个没有捕获。这个服务就完蛋了。你认为写if和写try有什么区别?我觉得除了try效率更低,多线程不稳定以外也没什么区别。
(4年前)&nbsp&
: 在并行开发中单一客户出错是可以允许的,出错就抛弃这个客户即可,路由器抛弃数据包,网站断开或者拒绝一个用户也很平常,重要的是服务端自己不能崩溃。错误扩大就抛弃这个客户即可,可是异常处理能如何?最后不还是要断开客户么。而且你要是不处理这个异常。整个服务就崩溃了。对于7*24这种级别的服务来说崩溃就什么都完了。
(4年前)&nbsp&
: 忽略了返回错误后,下面的也跟着出错会导致错误扩散,调试的时候会找不到出错点。
更悲剧的事情是下面接着的代码没有跟着出错,在忽略了出错信息后居然的到了看似正确的结果。
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
引用来自“LinkerLin”的答案非常不看好Go语言,理由:没有C++的基础好,没有Cython方便,没有C通用。也没有Java小白多。
难说啊,这些事情真的很难说啊,不过在我看来在现在的体系结构上,&C语言是最佳的语言抽象,很难找到一个层次定位比C语言更好的了,其实这就是一个唯一的问题,就算不是叫C语言,叫其它名字,它的内容表现也是一样的,就不是Denies发明的,也有其它人发明,内容和机制相似。唯一就是唯一。我觉得国防部门的底层开发培训讲的更好,更深。
--- 共有 1 条评论 ---
像C\C++这样的底层语言就不应该掺杂这么多高级特性,C++现在越搞越像动态语言了。这些底层语言就应该保证编码风格统一,实现方式使用最简单的语句稳定才是第一位的,然后高严格编码规范。工业标准,军工标准最好有个这样的部门。随着一代一代的C89,C99,C11诞生我觉得也不能总是用十几年前的编码方法了。
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
未经证明的技术都是扯淡
<span class="a_vote_num" id="a_vote_num_
不用go的飘过~
<span class="a_vote_num" id="a_vote_num_
引用来自“LinkerLin”的答案非常不看好Go语言,理由:没有C++的基础好,没有Cython方便,没有C通用。也没有Java小白多。
比那些语言好的地方在于背后有一个大公司支持
但比起Objective-C和C#来说,Go又找不到什么非用不可的理由.
更多开发者职位上
有什么技术问题吗?
红薯的其它问题
类似的话题golang(11)
C 语言属于第一种。函数调用出错时会返回特殊&#20540;,并有可能根据场景设置某个全局的(一般是 thread-local 的)错误代码。比如&printf函数正常情况下返回的是已输出的字符数,如果出错,就返回负&#20540;。Linux
(或其他遵循 POSIX 标准的 UNIX 系统) system calls 的函数传递错误信息的主要途径是设置全局的&errno&变量,这个变量保存的是当前线程最后一次发生的错误所对应的错误代码(详情见&man
errno)。Windows API 中也有类&#20284;的函数,叫&GetLastError,也是
thread-local 的。
这种风&#26684;的错误处理方式可以看作是一种历史遗留的存在,一方面是由于 C 语言本身比较古老,在错误处理的语言特性上不会有太大革新;另一方面主流的操作系统(Linux / UNIX / Windows)提供的系统调用大量使用了这种方式,也不会有太大改变。此种风&#26684;的优点是语言设计者不需要在错误处理方面花太多心思,而缺点是函数返回错误所能携带的信息很有限,往往需要额外的文档解释。另外,大多数语言都不会强制程序员检查返回&#20540;,这些错误很容易被忽略,而每个函数调用都检查返回&#20540;的话会令代码看上去非常啰嗦(所以我们很少去检查&printf&是不是返回了负&#20540;)。
Python, Ruby 和 JavaScript 都提供了异常处理机制,属于第二种。异常处理包括两部分,一是抛出,二是捕捉。语言的运行时环境以及用户代码都有可能抛出预定义的或用户自行定义的异常,在 Python 和 Ruby 中以类实例的形式存在,在 JavaScript 中可以是任意&#20540;。异常被抛出后,当前代码会终止执行,而异常会传递给上层的函数调用者——上层如果不处理这个异常,就继续往上抛,直到虚拟机捕捉到异常并终止整个程序的执行为止。异常的捕捉可以在当前代码块或外层代码块(如上层函数)中进行,其效果是:1.
阻止该异常的传递(也支持重新抛出) 2. 继续异常发生点之后的代码的执行(Ruby 提供的&retry&语句更强大,会重新执行触发异常的代码)。
很多主流的编程语言都采用了这种风&#26684;,尽管某些细节上存在差异。其优点是程序在标示错误时能提供更丰富的上下文,包括运行时环境和函数调用堆栈等信息,方便程序调试。代码看上去也会简洁很多,除了显式捕捉一些特别重要的(如 Rails 里的&ActiveRecord::RecordInvalid)之外,其他不需要特殊处理的异常,要么在最顶层添加通用的处理(比如在
Web 应用中显示 500 页面),要么直接终止程序运行并打印 backtrace 信息(试试&python
-m SimpleHTTPServer abc)。它的缺点没那么容易察觉,但也确实存在:程序中任何位置都有可能抛出异常,未捕捉的异常会终止程序的运行,而并不是所有程序都适合在顶层做通用的处理,所以写代码时总是要考虑两个问题:1. 我调用的代码会不会抛出异常 2. 我是否需要在当前代码中捕捉异常。对于大型项目的代码维护来说,这两个问题并没有那么容易确定,是个很大的思维负担(记住这一点,下文会有提及)。
初学 Go 语言时,以为它只是单纯继承了 C 语言的错误处理风&#26684;——在 Go 程序里到处都可以看到这样的代码:
f, err = os.Open(filename)
if err != nil {
fmt.Println(err)
读了 golang.org 上两篇关于错误处理的文章之后,才知道&error&接口的存在(我还以为它只是个内置的数据类型),并明白了&panic&和recover&的使用场景。
日常使用时,如果只是想返回一个简单的错误信息(比如&access
denied),只需return
errors.New(&xxx: access denied&),稍微复杂一点的可以用&errors.Errorf输出&#26684;式化的字符串。这里有一个编码约定,即错误信息本身要标明错误发生的上下文,比如&os.Open&返回的错误信息会是&open
/etc/passwd: permission denied&而不仅仅是&permission
在另外一些使用场景里,函数调用者会希望获取错误发生的更具体的信息,单靠字符串来传递这些信息显然不可行,替代的做法是定义一个新类型,实现它的&Error()&方法。这个方法会被&log.Fatal()&或&fmt.Println&之类的函数调用,把它当成一个普通的字符串,而需要读取额外信息的调用者,则用
type assertion 将&error&类型转换为实际的错误类型(代码来自&):
type SyntaxError struct {
string // description of error
Offset int64
// error occurred after reading Offset bytes
func (e *SyntaxError) Error() string { return e.msg }
// decoding json data
if err := dec.Decode(&val); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf(&%s:%d:%d: %v&, f.Name(), line, col, err)
return err
按照&这篇文章所说,Go 程序的一个惯例是对外的 API 尽量使用显式的&error&返回&#20540;,而内部错误处理可以根据需要使用&panic&和&recover&来简化流程。
关于两者的区别,Go 语言的核心开发者 Russ Cox 的解释是:在函数中如果出现了可预料的错误(比如网络连接失败,文件不存在,非法的 format 字符,等等),那就应该返回 error(&if your function is in any way likely to fail, it should return an error&)。如果是不可预料的(不应该出现的,“无法挽回的”)错误,比如数组越界(应该视作程序员的失误而不是程序运行环境的异常),那就是
panic. 按照 Go 的默认行为,&An unexpected panic like this is a serious bug in the program and by default kills it&,而如果你想避免程序因为这种异常退出,可以用 recover 机制。
在函数内部调用&panic&会立即终止当前函数的执行,由当前调用栈逐层返回,一直到最顶层的&main&函数或是被某一层的&recover&捕捉。panic&可以接收&#20540;作为参数,而这个&#20540;会由&recover&返回给调用者。在这个语义上&panic&和&recover&跟传统的&try...catch&很相&#20284;,但它们有一个很刻意的限制:panic&被调用时会立即终止当前函数,开始执行由&defer&指定的清理函数,然后返回上一层调用栈,这意味着&recover&只有在
deferred function (不知道怎么翻译)中才能起作用,不能像&try...catch&那样在任意位置捕捉异常。
以上所述的机制与 C 语言的错误处理风&#26684;相比,只改进了错误信息传递这部分,而代码冗余以及容易忽略错误的问题却没有解决,网上吐槽这个问题的人不止我一个,在&&这篇文章中,作者 ubershmekel 说由于它没有“现代的”错误处理机制,他暂时不考虑使用 Go 语言(&without modern error handling – I’m not going&)。
Russ Cox 在 Google Plus 的一个&&里回应了这篇文章。他解释了为什么
Go 要用函数返回&#20540;来表示错误而不是像目前的主流语言一样抛出异常。Russ Cox 说,在大型程序中判断是否要捕捉异常非常痛苦,影响开发效率(因为任何一个漏网的异常都有可能导致程序终止,降低了容错能力)。虽然 Go 语言的设计者也想让 Go 程序尽量简洁,但如果这种简洁是以增加大型程序维护成本为代价的话,就得不偿失了,这可以看作是语言设计上的一个折衷:
The error returns used by Go are admittedly inconvenient to callers, but they also make the possibility of the error explicit both in the program and in the type system. While simple programs might want to just print an error and
exit in all cases, it is common for more sophisticated programs to react differently depending on where the error came from, in which case the try &#43; catch approach is actually more verbose than explicit error results. It is true that your 10-line Python program
is probably more verbose in Go. Go's primary target, however, is not 10-line programs.
这篇 post 消除了我一半的困惑,但是函数调用返回的错误容易被忽略这个问题要怎么解决呢?Russ Cox 没说,ubershmekel 说大概可以用代码静态分析检测出来,不知道是否可行,需要进一步的研究。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:76923次
积分:1487
积分:1487
排名:千里之外
原创:67篇
转载:26篇
(3)(8)(1)(9)(10)(1)(7)(3)(1)(1)(2)(21)(3)(19)(4)

我要回帖

更多关于 c语言实现消息机制 的文章

 

随机推荐