defer在golang中很多地方进行使用,多数为文件输入输出,
同时,defer是栈的类型,LIFO last in first out, 后进先出模型。defer会在当前函数执行完毕后进行执行
如下方代码:
func d1() {
for i := 3; i > 0; i-- {
defer fmt.Print(i, " ")
}
}
func d2() {
for i := 3; i > 0; i-- {
defer func() {
fmt.Print(i, " ")
}()
}
}
func d3(){
for i := 3; i > 0; i-- {
defer func(n int) {
fmt.Print(n, " ")
}(i)
}
}
func main() {
d1()
fmt.Println()
d2()
fmt.Println()
d3()
}
d1, d2, d3分别打印:
1 2 3
0 0 0
1 2 3
我们发现,d2中,defer采用匿名函数,打印的是0 0 0, 这是因为defer是在函数所有代码执行完毕后执行,此时i已经自减到0了, defer匿名函数中使用的i变量与for循环i为同一内存。
d1在直接使用defer时 后面跟进函数,这个时候i进行了拷贝,并不与for中i共享内存
d3为定义匿名函数,同时传入参数值
推荐使用d3方法,保证每次将i进行拷贝把函数放入栈中