【golang学习之旅】延迟调用——defer

系列文章

【golang学习之旅】使用VScode安装配置Go开发环境
【golang学习之旅】报错:a declared but not used
【golang学习之旅】Go 的基本数据类型
【golang学习之旅】深入理解字符串string数据类型
【golang学习之旅】go mod tidy
【golang学习之旅】记录一次 panic case : reflect: reflect.Value.SetInt using unaddressable value
【golang学习之旅】记录一次 error case : full error output: cc1: error: unrecognized command line option
【golang学习之旅】Go程序快速开始 & Go程序开发的基本注意事项
【golang学习之旅】Go语言常用转义字符
【golang学习之旅】Go中的变量(1)
【golang学习之旅】Go中的变量——基本数据类型(1)
【golang学习之旅】Go中的变量——基本数据类型(2)
【golang学习之旅】复杂数据类型——指针 & 函数



defer特性

  1. 关键字 defer 用于注册延迟调用。
  2. 这些调用直到 return 前才被执。因此,可以用来做资源清理。
  3. 多个defer语句,按先进后出的方式执行。
  4. 每次defer语句执行时,会先计算出函数值和入参并保持起来;即,在执行defer语句时,延迟函数的入参已经确定,并保存了副本。

defer用途

及时释放资源。比如:

  1. 关闭文件句柄
  2. 锁资源释放
  3. 数据库连接释放

defer使用

defer 是先进后出的。

后面的语句会依赖前面的资源,因此如果先前面的资源先释放了,后面的语句就没法执行了

package main

import "fmt"

func deferTest() {
	defer fmt.Println("defer1")
	defer fmt.Println("defer2")
	fmt.Println("deferTest...")
}
func main() {
	deferTest()
	defer fmt.Println("defer3")
}

输出:
deferTest...
defer2
defer1
defer3
  • 当代码执行到defer时,暂时不会执行defer后的语句,而是将语句压入独立的栈(defer栈)。当函数执行完毕后,在从defer栈按照先进后出的方式执行

注意:

在defer将语句放入栈时,也会将相关的值拷贝同时入栈,这和函数调用是一样的。

package main

import "fmt"

func deferTest() {
	n1 := 1
	n2 := 2
	defer fmt.Println("defer1 n1=", n1, "n2=", n2)
	n1++
	n2++
	defer fmt.Println("defer2 n1=", n1, "n2=", n2)
	n1++
	n2++
	fmt.Println("deferTest... n1=", n1, "n2=", n2)
}
func main() {
	deferTest()
	defer fmt.Println("defer3")
}

输出:
deferTest... n1= 3 n2= 4
defer2 n1= 2 n2= 3
defer1 n1= 1 n2= 2
defer3

最佳实践

在函数执行完毕后,可以及时地释放函数创建的资源,该操作不需要写在代码末尾(很容易忘记这个步骤),直接写在创建资源代码后面。

这种机制让程序员不再为什么时机关闭资源而烦恼

// 在打开文件资源后立即defer关闭文件资源,当然关闭操作会在程序退出时执行
	file := openFile(文件名)
	defer file.Close()
	//其他代码

	// 在连接数据库后立即defer释放数据库资源,当然关闭操作会在程序退出时执行
	connect = connectDB(dbName)
	defer connect.Close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不怕娜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值