golang学习系列——15. defer

目录

 

1. defer 的基本功能

2. 应用场景举例

3. 注意事项


1. defer 的基本功能

defer后面只能跟函数调用语句,defer把该语句执行的时间推迟到执行结束的时候

用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块,它一般用于释放某些已分配的资源。

func test() {
	defer fmt.Println("out test")
	fmt.Println("enter test")
	//todo
}

func main() {
	test()
}

 

2. 应用场景举例

1. 关闭文件流

//open a file  
defer file.Close()

2. 解锁一个加锁的资源

mu.Lock()
defer mu.Unlock()

3. 打印最终报告

printHeader()  
defer printFooter()

4. 关闭数据库链接

// open a database connection  
defer disconnectFromDB()

5. 使用 defer 语句实现代码追踪

6. 使用 defer 语句来记录函数的参数与返回值

3. 注意事项

1. 当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出)

func test() {
	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("out test")
}

结果打印如下

2. defer函数参数的计算时间点

func test(arg int) {
	defer fmt.Println("defer arg is ", arg)
	arg += 2000
	fmt.Println("out arg is ", arg)
}

func main() {
	test(100)
}

结果打印如下

可以看到 defer 语句只是延迟了执行函数的时机,并没有延迟传递参数的时机

3. 用defer调用多条函数语句

我们可以使用匿名函数来调用多条语句

func test(arg int) {
	defer func() {
		arg += 12
		fmt.Println("defer arg is ", arg)
	}()
	arg += 2000
	fmt.Println("out arg is ", arg)
}

func main() {
	test(100)
}

执行结果如下

有趣的事情发生了,这里 defer 语句打印的结果居然是 2112 ?推测解释如下:

在这里 defer 并没有传递参数,功能只是把这个匿名函数推迟调用了而已,然后匿名函数使用了arg这个局部变量

func test(arg int) {
	defer func(a int) {
		a += 12
		fmt.Println("defer arg is ", a)
	}(arg)
	arg += 2000
	fmt.Println("out arg is ", arg)
}

func main() {
	test(100)
}

执行结果如下

4. 使用defer函数影响宿主函数的返回值

由上面的例子我们可以知道,在函数内部使用匿名函数是可以直接使用函数内部的局部变量的(有点拗口)

那么 [ defer + 匿名函数 ] 的组合当然也可以修改函数的返回值(这是需要我们警惕的点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值