Golang中的defer、panic与recover关键字
一、defer关键字
1.defer关键字定义了在当前函数生命周期结束之前触发的一种机制,类似于C++中的析构函数,Java中的final关键字。如在main函数中定义: defer fmt.Println("end"),表示会在main函数结束前输出end。
2.defer可在同一函数体中定义多个,执行顺序类似压栈,后定义的defer语句先执行。
3.当同一函数体中同时出现defer语句和return语句时,return语句会先于defer语句执行。
4.对于函数的命名返回值和匿名返回值,defer语句的表现不同。
5.defer语句注册要延迟执行的函数时,如若有参数,首先要确定所有参数的值。
6.定义如下函数:
func f1() int {
x := 5
defer func() {
x++
}()
return x
}
func f2() (x int) {
defer func() {
x++
}()
return 5
}
func f3() (y int) {
x := 5
defer func() {
x++
}()
return x
}
func f4() (x int) {
defer func(x int) {
x++
}(x)
return 5
}
调用并输出结果:
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
fmt.Println(f4())
}
结果为:5 6 5 5
(1)f1中返回值为匿名返回值,先执行return语句,将x(此时为5)赋值给返回值,再执行defer语句注册的函数,修改了x的值,但未修改返回值,因此输出5。
(2)f2中返回值为命名返回值,即x代表最终返回值,先执行return语句,将5赋值给返回值x,再执行defer语句注册的函数,x++,此时返回值x的值为6,因此输出6。
(3)f3中返回值为命名返回值,即y代表最终返回值,原理同(2),但由于最终返回值为y,修改x的值不影响y的值,因此输出5。
(4)f4中返回值为命名返回值,即x代表最终返回值,由于defer语句注册的函数是自执行函数且x作为该函数的参数,首先要让该函数参数确定,因此先把x(此时初始为0)传入该函数,此时x为1,再把5赋值给返回值x,此时返回值为5,因此输出5。
二、panic与recover关键字
1.两关键字主要用于异常处理中,panic负责抛出异常,recover获取panic抛出的异常
2.recover语句只可定义在defer注册的函数里。