1.Go语言中的defer关键词
Go语言的defer关键词是在Go语言函数结束后执行的语句,我们用一段代码直接感受defer关键词的作用:
package main
import "fmt"
func deferRun() {
fmt.Println("defer fucntion is run")
}
func main (){
// 定义一个函数结束后需要执行的方法
defer deferRun()
fmt.Println("main function is run")
}
运行结果:
main function is run
defer fucntion is run
可以看到,主函数main在执行完毕之后,系统随之调用了deferRun方法,说明在函数结束后调用了defer关键词后面的函数,这也是defer关键词的作用,这与c++中的析构函数或者和Java中的finally关键词有些类似,但是defer关键词是函数整个生命周期结束后才调用,我们知道return关键词代表一个函数的结束,我们可以通过比较defer关键多次和return关键词结束的先后顺序来说明:
package main
import "fmt"
func deferRun() int{
fmt.Println("defer fucntion is run")
return 0
}
func returnRun() int{
fmt.Println("return fucntion is run")
return 0
}
func returnAnddefer() int{
defer deferRun()
return returnRun()
}
func main (){
returnAnddefer()
}
运行结果:
return fucntion is run
defer fucntion is run
可以看到,return是先于defer执行的,这也说明了defer是函数整个声明周期结束后才会起作用。
2.Go语言defer的执行顺序
一个函数如果有多个defer,那么执行顺序是怎么样的呢,同样的,我们看个例子:
package main
import "fmt"
func deferRun1() {
fmt.Println("defer fucntion1 is run")
}
func deferRun2() {
fmt.Println("defer fucntion2 is run")
}
func deferRun3() {
fmt.Println("defer fucntion3 is run")
}
func main (){
defer deferRun1()
defer deferRun2()
defer deferRun3()
}
运行结果:
defer fucntion3 is run
defer fucntion2 is run
defer fucntion1 is run
可以看到,执行顺序与我们的定义的顺序正好相反,这是由于Go语言在处理defer关键词的时候采用的是压栈的方式,了解栈这个数据结构的小伙伴可能就明白,栈的最大的特点就是先入后出,即每出现一个defer就将其后的函数压入栈中,在函数体结束后,再一个个取出执行。所以执行顺序与我们的定义顺序正好相反。