简单介绍的defer
defer是什么?
在Go语言中,可以使用关键字defer向函数注册退出调用,即主函数退出时,defer后的函数才被调用。defer语句的作用是不管程序是否出现异常,均在函数退出时自动执行相关代码。
defer的用途
在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等) ,为了在函数执行完 毕后,及时的释放资源,Go 的设计者提供 defer (延时机制)。
规则二:延迟函数执行按后进先出顺序执行,即先出现的defer最后执行
规则三:延迟函数可能操作主函数的具名返回值
package main
import "fmt"
func fun() {
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
defer func(){
recover()
fmt.Println("捕获到panic")//在函数返回前,defer语言可以捕获到,决定是否recover
}()
panic("制造异常")
//panic一般代码中不出出现,当程序员认为程序执行到此处出现了问题才使用,类似异常处理
}
func main() {
fun()
}
捕获到panic
3
2
1
return原理和defer的执行时机
验证一下:
import "fmt"
func add() (ret string) {
defer fmt.Println("erhuo")
return "zhangwei"
}
func main() {
add()
}
练习一下:
package main
import "fmt"
func fun1() int {
ret := 5
defer func() {
ret++
}()
return ret
//假设返回的int命名为x 1.return返回值:y=ret(ret=5) 2.defer语句:ret++(ret=6) 3.RET指令返回y是5
}
func fun2() (ret int) { //这里指定了返回值是ret
defer func() {
ret++
}()
return 5 //1.return返回5赋值给ret 2.defer语句:ret++(ret=6) 3.RET指令,返回值ret是6
}
func fun3() (y int) {//指定返回值是y,
x := 5
defer func() {
x++
}()
return x
//y=x(x=5) defer:x++(x=6) RET指令 返回y(是5)
}
func fun4() (x int) {
fmt.Printf("返回值x:%p\n", &x)
defer func(x int) { //匿名函数的参数x
x++ //匿名函数传参进来的x
fmt.Printf("匿名函数内的x:%p\n", &x)
}(x) //fun4的返回值x,传参给匿名函数,值传递就是值copy,这个x和fun4返回值的x不同地址
return 5 // func4的返回值x=5 defer:匿名函数内的x++ RET指令func4的返回值x=5
}
func main() {
fmt.Println(fun1())
fmt.Println(fun2())
fmt.Println(fun3())
fmt.Println(fun4())
}
如此猜想,执行RET指令时候已经跳出了add函数,所以add函数中的局部变量不能引用到。