defer意思是推迟、延迟。语法很简单,就在正常的语句前加上defer就可以了。
? 在某函数中使用defer语句,会使得defer后跟的语句进行延迟处理,当该函数即将返回时,或发生panic时,defer后语句开始执行。注意os.Exit不是这两种情况,不会执行defer。
? 同一个函数可以有多个defer语句,依次加入调用栈中(LIFO),函数返回或panic时,从栈顶依次执行defer后语句。执行的先后顺序和注册的顺序正好相反,也就是后注册的先执行。
defer后的语句必须是一个函数或方法的调用
//执行的先后顺序和注册的顺序正好相反,也就是后注册的先执行。
package main
import "fmt"
func main() {
fmt.Println("start")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println("end")
}
start
end
3
2
1
package main
import "fmt"
func main() {
count := 1
fmt.Println("start")
defer fmt.Println(count) //1
count++
defer fmt.Println(count) //2
count++
defer fmt.Println(count) //3
fmt.Println("end")
}
start
end
3
2
1
//为什么?因为defer注册时就,就把其后语句的延迟执行的函数的实际参数准备好了,也就是注册时计算。
package main
import "fmt"
func main() {
count := 1
fmt.Println("start")
defer func() { fmt.Println(count) }() // fmt.Println(count) 因为注册时要确定实际参数,而这是个匿名无参函数,没法准备参数。延迟执行时,打印是才要用count,其外部作用域有一个count,目前是3。
count++
defer fmt.Println(count)
count++
defer fmt.Println(count)
fmt.Println("end")
}
start
end
3
2
3
package main
import "fmt"
func main() {
count := 1
fmt.Println("start")
defer func(count int) { fmt.Println(count) }(count) //确定了实际参数,直接传参进去为1
fmt.Println(count)
count++
defer fmt.Println(count)
count++
defer fmt.Println(count)
fmt.Println("end")
}
start
1
end
3
2
1