Go 语言 函数defer的使用
一、基本概念:
在函数中,经常需要创建资源(比如:数据库的连接、文件、锁等),为了在函数执行完毕后,及时释放资源,go 提供了defer(延时机制)
。
举个栗子:
package main
import "fmt"
// 当执行到defer 时, 暂时不会执行, 会将defer 后面的语句 压入到 栈中(特点:先进后出)
// 当函数执行完毕后, 在从 栈中 依次取出 并执行
func sum(num1 int, num2 int) int {
defer fmt.Println("ok1 num1=", num1)
defer fmt.Println("ok2 num2=", num2)
// 上述两个语句,已经入栈后, 来更改参数, 校验是否入栈时,将对应的值也进行了拷贝
result := num1 + num2
fmt.Println("ok3 result", result)
return result
}
func main() {
result := sum(10, 20)
fmt.Println("main()函数结果", result)
}
// 输出结果:
ok3 result 30
ok2 num2= 20
ok1 num1= 10
main()函数结果 30
二、使用细节:
-
当 go 执行到一个defer时, 不会立即执行 defer 后语句,而是将 defer 后的语句压入到栈中(先进后出),然后继续执行函数下一个语句。
-
当函数执行完毕后,在从defer 栈中,依次从 栈顶取出语句执行。
-
在defer 语句放入到栈时,也会将相关的值拷贝并进行入栈:
func sum(num1 int, num2 int) int { defer fmt.Println("ok1 num1=", num1) // 值还是 10 defer fmt.Println("ok2 num2=", num2) // 值还是 20 // 上述两个语句,已经入栈后, 来更改参数, 校验是否入栈时,将对应的值也进行了拷贝 num1++ // 10 + 1 num2++ // 20 + 1 result := num1 + num2 // 11 + 21 fmt.Println("ok3 result", result) // result 值为 32 return result } // 输出结果: ok3 result 32 ok2 num2= 20 ok1 num1= 10 main()函数结果 32