Golang_defer执行顺序
目录
Golang defer
Golang defer 执行时机
defer 语句在声明时,会立即计算其参数的值并将函数与参数绑定,但函数体的执行会延迟到外层函数即将返回时。
如果在函数中有多个 defer,它们会按照后进先出的顺序执行,类似栈结构
看下面的例子
|
|
defer 和匿名函数的一些问题和疑惑
直接声明 defer 匿名函数,参数不通过匿名函数的参数传入
这个其实就是 匿名函数捕获外部变量(闭包行为):
- 匿名函数会捕获变量的引用(即变量地址),而不是变量值。
- 如果变量在 defer 注册之后发生了变化,匿名函数使用的值也会随之变化。
|
|
像上面这个例子,我们的 x 不是通过参数从匿名函数传入的,所以对于 x 这个值的获取,是在程序 return 前才获取的,也就是 30
直接声明 defer 匿名函数,参数通过匿名函数的参数传入
这个就是传入参数立即求值: 如果在 defer 调用时直接传递参数,那么这些参数会在 defer 声明时立即计算并存储。
|
|
与 return 的关系
1.函数遇到 retrun 的时候,会先记录返回值,然后执行 defer 语句,最后再真正返回
当函数遇到 return 时,会先记录返回值(如果有),然后执行 defer 语句,最后再真正返回。
例子:
|
|
解释:
example
函数开始执行,打印"Function is executing"
。- 遇到
return 42
时,函数会先记录返回值42
,但不会立即返回。 - 接着,
defer
语句fmt.Println("Deferred statement executed")
被执行,打印"Deferred statement executed"
。 - 最后,函数真正返回,
main
函数接收到返回值42
并打印"Main function received: 42"
。
这个例子展示了 defer
语句在 return
之后、函数真正返回之前执行的特性。
2. 可以在 defer 函数中修改返回值
如果函数有具名返回值,defer 中可以修改返回值。
|
|
defer 异常捕获与处理
通过 defer 结合 recover 函数,可以在发生异常时进行恢复操作,并获取异常信息进行处理。例如:
|
|
底层机制
面试题
形成了闭包,这个匿名函数会捕获我们的变量 x 的引用,defer 会在 return 保存值后执行,所以这个时候 x 已经变成 x+1 了,所以 print 打印的值是 x + 1
如果把 x 从匿名函数的参数传入,那么就不会形成闭包,这些参数会在 defer 声明时立即计算并存储,这样的话,打印出来就还是 x 了