Go语言中用于错误处理的Defer、Panic和Recover - Sachin Karve


许多开发人员在开始开发企业级应用程序之前,往往会忽略编程语言的错误处理机制。最好以一种可以从异常中恢复(万一发生)的方式开发代码。
不同的编程语言以不同的方式处理错误,异常和恢复。Go采用了Defer、Panic和Recover的方式,彼此密切配合以确保程序的顺利执行。
 
Defer
Defer关键字将一个函数转换为一种特殊的函数类型,在调用该函数时,它会添加到已保存的函数调用列表中。当需要返回包裹函数时,这个函数调用列表将被执行。此处,包裹函数是指在其中defer被调用的函数。
目的:该函数在调用时得到评估,但在返回包裹函数时执行。
工作原理:一旦在程序执行期间调用了此函数,它将确保两件事:

  1. 该函数及其参数值在调用时将进行评估。
  2. 该函数计划在包裹函数返回之前立即执行。

Defer通常在打开文件、新的内存块或数据库连接时使用,以在函数完成执行之前正常关闭它。即使该函数由于代码中的任何错误而无法中途执行,它也可以工作。
 
Panic
正如官方网站所解释的,Panic是“一种内置功能,可以停止普通的控制流并开始恐慌panicking ”。它可以在执行流程中调用异常。当发生错误或异常情况时,可以通过编程方式或运行时来调用Panic。
对于了解Java的人来说,它类似于throw()。
目的:停止通常的执行流程。可能是由于异常情况(例如运行时错误)或程序员有意调用导致的。
工作:调用此函数后,通常的执行流程将停止,程序进入紧急模式。如果堆栈上有任何延迟调用,则程序将执行那些延迟调用,否则将在紧急模式下返回其调用方,并在调用堆栈中继续执行。
注意,当运行环境调用panic时,我们的panic函数未处理它。当panic是由运行环境引起时,我们需要一种不同的机制来使执行回到正轨。它称为Recover()。
 
Recover
根据官方网站的说法,Recover 是“一种内置功能,可以重新获得对panic goroutine的控制权”。

当且仅当在defer函数中调用Recover时,才可以使用Recover。通常,调用recover会简单地返回一个nil值。
同样,当且仅当函数已经进行了defer调用时,才可以捕获panic。理解这一点对于使用Recover 至关重要。
目的:它旨在使系统在出现紧急情况后恢复正常。
工作:在defer函数中调用时,执行流程如下:

  1. 当执行例程panic时,正常执行停止,例程尝试返回
  2. 由于例程在panic之前已经进行了defer调用,因此defer在例程返回之前被调用
  3. 现在,在defer中,我们放置recover调用,该调用捕获紧急事件的参数并继续进行恢复;恢复进一步继续执行。

参考:
为什么Golang现在还不能用于构建企业系统的原因 - Dmitry