- defer语句会将其后面跟随的语句进行延迟处理
- 先被defer的语句最后执行,最后被defer的语句最先被执行
fmt.Println("start")
defer fmt.Println(1) // 将defer放入延迟调用栈,先放的位于栈底被最后执行
defer fmt.Println(2)
defer fmt.Println(3) // 最后放的位于栈顶,最先调用
fmt.Println("end")
defer begin
defer end
3
2
1
defer用途
- 关闭文件句柄
- 资源释放
- 数据库连接释放
defer存在时return的执行逻辑
defer、return、返回值三者的执行逻辑是:
- return最先执行,return将值写入返回值中
- 然后defer开始执行延迟函数
- 最后函数携带当前返回值退出
当defer放在return后面时就不会被执行
func deferFuncReturn() (result int) {
i := 1
defer func() {
result++
}()
return i
}
执行顺序:
result = i //先将i值写入返回值中
result ++ //再执行defer
return //函数结束
主函数返回值有命名时,defer可能会影响返回值
func TestFunc() (result int) {
defer func() {
result = 1024
}()
return 2048
}
func main() {
fmt.Println(TestFunc())
}
执行顺序;
result = 2048 //先将return 2048写入到返回值中
result = 1024 //再执行defer函数,result=1024
return //函数结束,结果是1024
主函数拥有的是匿名返回值时,defer无法操作返回值
func TestFunc() int {
result := 1024
defer func() {
result = 2048
}()
return result
}
func main() {
fmt.Println(TestFunc())
}
执行结果:1024
1、defer func虽然更新了result的值,并没有对函数返回值造成影响。原因是该函数的int类型返回值未命名(即匿名返回值),所以 defer func无法修改该返回值,只是修改了result变量值