defer的使用
golang中的defer延迟特性让c/c++中常忘记释放的对象的问题以及panic延迟,很好的解决了。现在看一下defer是如何处理的?
使用defer时,会开辟一个单独的栈空间,将紧跟在defer关键字之后的逻辑放入此栈中,但是当多个defer套用时又是如何处理的。
func main(){
functest(func() {
fmt.Println("second exec") //验证函数参数中包含函数指针的执行顺序
})
time.Sleep(1 * time.Second)
}
func functest(fn func ()){
fmt.Println("fist exec,") //验证函数参数中包含函数指针的执行顺序
defer func(){ //第一个defer
defer func(){ //第一个defer中嵌套的defer
fmt.Println("firth exec")
}()
fmt.Println("forth exec ")
}()
i := 0
defer func(i int){ //第二个defer
fmt.Println("third exec")
}(i)
fn() //验证函数参数中包含函数指针的执行顺序
}
按照程序的执行,首先会将第一个defer后紧跟的逻辑放入特殊的栈中,然后将第二个defer后紧跟的逻辑放入栈中。这两个好理解但是第一个defer后紧跟逻辑中的defer是如何存储的?按照defer的性质将其放在新的特殊栈中。按照栈先进后出的逻辑,所以显示结果如下:
fist exec,
second exec
forth exec 0
third exec
firth exec
代码注释中“验证函数参数中包含函数指针的执行顺序”这个是联系中自己添加的思路,本文可以直接忽略,这篇文章只是简单介绍多个defer的执行顺序,下篇文章会专门讲解defer的实现。