面试题答案
一键面试-
defer、panic、recover的交互关系:
- defer:defer语句用于延迟函数的执行,在包含defer语句的函数即将返回时,会按照defer语句出现的逆序依次执行这些延迟的函数。
- panic:panic用于抛出异常,使程序进入恐慌状态,会停止当前函数的正常执行,并开始展开调用栈。在展开调用栈的过程中,会执行该函数中已定义的defer语句。
- recover:recover只能在defer函数中使用,用于捕获panic抛出的异常,使程序从恐慌状态恢复正常执行。如果在defer函数之外调用recover,将返回
nil
。
-
代码示例及执行流程:
package main
import (
"fmt"
)
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in main:", r)
}
}()
fmt.Println("Before calling f")
f()
fmt.Println("After calling f")
}
func f() {
defer func() {
fmt.Println("First defer in f")
}()
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f:", r)
}
}()
defer func() {
fmt.Println("Second defer in f")
}()
fmt.Println("Before panic in f")
panic("Panic in f")
fmt.Println("After panic in f")
}
- 执行流程:
- 在
main
函数中,首先打印Before calling f
。 - 调用
f
函数,f
函数中首先打印Before panic in f
。 - 遇到
panic("Panic in f")
,f
函数停止正常执行,开始执行defer函数,按照逆序执行,先打印Second defer in f
,再打印First defer in f
。 - 第二个defer函数中,
recover
捕获到panic
,打印Recovered in f: Panic in f
。 f
函数结束,回到main
函数,main
函数继续执行,打印After calling f
。因为f
函数中的panic
被f
函数内的recover
捕获,所以main
函数的defer函数中的recover
不会捕获到异常。
- 在
执行结果:
Before calling f
Before panic in f
Second defer in f
First defer in f
Recovered in f: Panic in f
After calling f