golang-defer的一点坑

本文详细解析了Go语言中defer关键字的执行原理,通过四个示例代码展示了defer及其后函数的执行时机与变量计算时刻,揭示了defer如何在函数返回前执行收尾工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

defer 允许我们进行一些函数执行完成之后的收尾工作,并且代码更加简洁,如:

1. 关闭文件流

defer file.close()

2. 解锁加锁的资源

mu.lock()
defer mu.Unlock()

3. 最终打印

printHeader()
defer printFooter()

4. 关闭数据库连接

defer disconnectFromDB()

但是,很多朋友可能没有深入研究过一些问题:

defer和defer后的函数何时执行?

defer后函数中的变量何时计算?

请看下面一个例子。

package main

import "fmt"

func test1() (x int){
	defer fmt.Println("in defer: x =", x)
	x = 7
	return 9
}


func test2() (x int) {
	x = 7
	defer fmt.Println("in defer x =", x)
	return 9
}

func test3() (x int) {
	defer func() {
		fmt.Println("in defer x =", x)
	}()
	x = 7
	return 9
}

func test4() (x int) {
	defer func(n int){
		fmt.Println("in defer x as parameter: x =", n)
		fmt.Println("in defer x after return: x =", x)
	}(x)
	x = 7
	return 9
}


func main() {
	fmt.Println("--------------test1--------------")
	test1()
	fmt.Println("--------------test2--------------")
	test2()
	fmt.Println("--------------test3--------------")
	test3()
	fmt.Println("--------------test4--------------")
	test4()
}

输出结果:

--------------test1--------------
in defer: x = 0
--------------test2--------------
in defer x = 7
--------------test3--------------
in defer x = 9
--------------test4--------------
in defer x as parameter: x = 0
in defer x after return: x = 9

defer的执行原理

想知道执行结果为什么是这样,那么就需要回答前面的两个问题:

1. defer和defer后的函数何时执行?

2. defer后函数中的变量何时计算?

问题1:

defer在defer关键字处执行,defer是把被defer的函数压入栈,等待return或panic后,再按先进后出的顺序执行被defer的函数。

问题2:

被defer函数的参数是在执行defer时计算的,函数中的变量的值是在函数执行时计算的。

defer及被defer函数的执行步骤:

1. 执行defer,计算函数入参的值并传递给函数,但不执行函数,而是将函数压入栈。

2. 当函数return或panic时,执行压入栈的函数(被defer的函数),此时,计算被defer的函数中变量的值。

所以,我们可以解释这种结果:

test1:传参,由于前面没有定义x,Println中形参x的值为0。

test2:同理,由于前面定义了x值为7,故形参x的值为7。

test3:由于内层函数可以访问外层函数的变量,当外层函数return后,读取x的值为9。

test4:传参,由于前面n未定义,故n为0;同test3,x的值为9。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值