defer后面的函数在Go程序设计语言中被称为延迟函数,为什么叫延迟呢?因为这个defer函数的存在于一个函数之中(包括main函数),defer函数执行的时机是在 包含他的那个函数(上一层函数)将要执行完之前的最后一步,即函数最后一条语句执行完了,然后在执行这个defer函数,如果同一个函数内部有多个defer的函数,那么,这些个defer函数的执行顺序按照栈的后进先出,最后定义的defer函数最先执行,最先定义的defer函数最后执行。
类似于 有一个人生了儿子(可能是生了几个儿子,也可能只有一个),这个人的儿子都特别懒,在他活着的时候,他的儿子什么事都不干,等他快死的时候,吩咐一大堆事情,需要让他儿子们来处理,如果只有一个儿子,那这个就好办,所有的事情都得让他处理,如果又多个儿子,那么,老大推给老二,老二推给老三,老三做了一些事就跑了,还留了一些给老二处理,老二处理了一些也跑了,剩下的全让老大处理了,等老大处理完之后,他老子才放心的闭眼死去。 在这个例子中,这些个儿子就是延迟函数。
先看一个简单的例子:
package main import "fmt" func main(){ defer func(){ fmt.Println("run last") }() //注意defer的函数后面一定要加圆括号,不然就是定义函数,而不会执行函数 fmt.Println("run first") }
在上面这个例子中,包含defer函数的 函数是main函数,所以在main()函数执行完毕之后(不能说main函数执行完毕,应该说已经顺序执行完除了defer函数以外的所有语句),才执行defer函数,所以运行结果如下:
run first run last
然后看下面这个例子:
package main import "fmt" func test(){ fmt.Println("One") defer func(){ fmt.Println("two") }() defer func(){ fmt.Println("three") }() } func main(){ test() fmt.Println("run first") }
上面这个例子中test函数包含在main()中,test函数中包含两个延迟函数,所以正常语句执行完之后,应该先执行第二个延迟函数,然后执行第一个延迟函数,然后test函数执行完毕后,在顺序执行test函数后面的语句。
One three two run first
在看一个例子:
package main import "fmt" func test(){ fmt.Println("One") defer func(){ fmt.Println("two") }() defer func(){ fmt.Println("three") }() } func main(){ defer test() #与上面一个例子的区别,这里test函数是延迟函数 fmt.Println("run first") }
因为test函数此时作为延迟函数,那么test函数在main函数中最后执行,执行test的时候,因为test中又有延迟函数,仍旧遵守上面的顺序,所以执行的结果如下:
run first One three two
延迟函数类似于其他面向对象语言中的析构函数,只是很类似,不要混为一谈。延迟通常用来做一些收尾工作,给他的主子擦屁股,比如关闭打开的文件,或者一些连接状态,亦或者清楚一些数据。。。。。