更多干货:关注公众号 奇伢云存储
Golang 的 defer
是什么?通俗来讲就是延迟调用。defer 会在当前函数返回之前执行 defer
注册的函数。比如 defer func_x( )
这样语句会让你注册一个函数变量到 defer 的全局链表中,在 defer 语句所在的函数退出之前调用。
笔者使用一段时间 Golang 之后,对 Golang defer 的理解认为作用有两点:
- panic 场景依然会被调用:这个是重要的一个特性,通常能简化我们的代码,确保无论任何场景,defer 的函数一定调用,通常用在锁或者资源的释放场景较多;
- 配套的两个行为代码可以放在最近的位置:创建&释放、加锁&放锁、前置&后置,使得代码更易读,编程体验优秀。最近的地方是哪里?下一行;
先看下 defer 的以下几个特性:
defer 的特性
我们先深入的剖析下 defer 具有的特性,知其然也。这些特性是需要我们记住的特点,才能更好的理解 defer
使用的场景。
延迟调用
package main
func main() {
defer println("--- defer ---")
println("--- end ---")
}
defer
会在 main 函数 return 之前时候调用。核心要点:
- 延迟调用:
defer
语句本身虽然是main
的第一行,但是 fmt.Println 是先打印的; defer
关键字一定是处于函数上下文:defer
必须放在函数内部;
LIFO
一个函数中有多个 defer 调用怎么办?
压栈式执行,后入先出。
package main
import (
"strconv"
)
func main() {
for i := 1; i <= 6; i++ {
defer println("defer -->" + strconv.Itoa(i))
}
println("--- end ---")
}
压栈式执行,也就是说先注册的函数后调用。如上,我们注册的顺序式 1,2,3,4,5,6,最后打印 “— end —”,所以执行的结果自然是