golang defer 关键知识点汇总

本文深入探讨了Go语言中defer关键字的使用方法及其注意事项。详细解释了defer如何实现资源的回收和释放,并通过示例展示了其先进后出的执行顺序。此外,还特别提到了在不同场景下defer的行为差异。

(1)defer 关键字,可以用来注册多个延迟调用,这些调用以先进后出(FILO)的顺序 在函数返回前被执行。常用于保证一些资源最终一定能够得到回收和释放。

(2)关于defer的使用,主要注意以下几点:

  • defer后面必须是函数或方法的调用,不能是语句,否则会报 expression in defer must be function call 的错误。

  • defer函数的实参在注册时通过值拷贝传递。
func main() {
	f()
    //输出 defer i= 0
}

func f() int {
	v := 0
	//值拷贝
	defer func(i int) {
		println("defer i=", i)
	}(v)

	v++
	return v
}
  • defer语句必须先注册后才能执行,如果defer位于return之后,则 defer 没有注册,不会执行。
func main() {

	//先进后出
	defer func() {
		println("first")
	}()

	defer func() {
		println("second")
	}()

	println(" main body ")

	p := 1
	println("p=", p)

	//return语句返回
	return

	defer func() {
		println(" third ") //之前有return 不会输出
	}()

}

//output:
// main body
// p=1
//second
//first
  • 主动调用os.Exit(int)退出进程时,defer将不再被执行,此种情况,是有条件的 :
  1. os.Exit(int)方法之前无return语句
  2. os.Exit(int)方法调用之前如果调用了子函数且子函数中有defer语句,则子函数中的defer语句也会被执行。
func main() {
	f()
	defer func() {
		println("my defer ")
	}()
	println("func body")
	//return
	os.Exit(1)

	//output:
	//defer i= 0
	//func body
}

func f() int {
	v := 0
	//值拷贝
	defer func(i int) {
		println("defer i=", i)
	}(v)

	v++
	return v
}
  • defer语句的位置不当,也会引起panic,一般defer语句放于错误检查语句之后。
  • 因defer会推迟资源的释放,defer尽量不要放于循环语句中。
  • defer 中 最好不要对有名返回值参数进行操作,否则会引起莫名其妙的结果。
func main() {
	f()
	loop()
	//先进后出
	defer func() {
		println("first")
	}()

	defer func() {
		println("second")
	}()

	println(" main body ")

	p := 1
	println("p=", p)

	//return 之前 主动调用os.Exit(int),如果之前有调用子函数,子函数的defer语句还会执行。
	os.Exit(1)

	//return语句返回
	return

	defer func() {
		println(" third ") //之前有return 不会输出
	}()

}

//output:
//defer i= 0
//loop= 4
//loop= 3
//loop= 2
//loop= 1
//loop= 0
//main body
//p= 1

func f() int {
	v := 0
	//值拷贝
	defer func(i int) {
		println("defer i=", i)
	}(v)

	v++
	return v
}

//测试放于循环语句中的输出
func loop() {
	for i := 0; i < 5; i++ {
		defer println("loop=", i)
	}
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DreamCatcher

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

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

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

打赏作者

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

抵扣说明:

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

余额充值