3.6 Go语言函数的延迟调用(Deferred Code)

Python07

3.6 Go语言函数的延迟调用(Deferred Code),第1张

在以下这段代码中,我们操作一个文件,无论成功与否都需要关闭文件句柄。这里在三处不同的位置都调用了file.Close()方法,代码显得非常冗余。

我们利用延迟调用来优化代码。定义后的defer代码,会在return之前返回,让代码显得更加紧凑,且可读性变强,对上面的代码改造如下:

我们通过这个示例来看一下延迟调用与正常代码之间的执行顺序

先简单分析一下代码逻辑:

从输出中,我们可以观察到如下现象:

从这个实例中,我们很明显观察到,defer语句是在return之前执行

如果一个函数内定义了多个defer,则调用顺序为LIFO(后进先出)方式执行。

仍然是相同的例子,但是在TestDefer中我们定义了三个defer输出,根据LIFO原则,输出的顺序是3rd->2nd->1st,根据最后的结果,也是逆向向上执行defer输出。

就在整理这篇笔记的时候,发现了自己的认知误区,主要是本节实例三中发现的,先来看一下英文的描述:

对于上面的这段话的理解:

下面是代码执行输出,我们来一起分析一下:

虽然在a()函数内,显示的返回了10,但是main函数中得到的结果是defer函数自增后的结果,我们来分析一下代码:

在这篇文章的上一版,我曾经尝试用指针取解释defer修改返回值的类型,但是感觉不够透彻,也让阅读者非常困惑,索性参考了一下go官方blog中的一篇文章,在此基础上进行了扩展。如需要阅读原文,可以参考下面的文章。

1、goroutine:在go语言中,每一个并发的执行单元叫做goroutine,如果一个程序中包含多个goroutine,对两个函数的调用则可能发生在同一时刻

2、main goroutine:当一个程序启动时,其主函数即在一个单独的goroutine中运行,我们叫他为main gorountine

3、go goroutine:新的goroutine会用go语句来创建,go+函数名,go语句会使其语句中的函数在一新创建的goroutine中运行,而go语句本身会迅速地完成

4、goroutine的退出:主函数返回时,所有的goroutine都会被直接打断,程序退出,除了从主函数退出或者终止程序之外,没有其他方法能够让一个goroutine来打断另一个的执行,但是可以通过另一种方式来实现这个目的,通过goroutine之间的通信来让一个goroutine请求其他的goroutine,并让请求的goroutine自行结束执行