面试题答案
一键面试在Go语言中,当一个函数内部发生panic
时,panic
会立即停止当前函数的执行,并开始在调用栈中向上传播。具体过程如下:
- 当前函数停止执行:
panic
发生后,当前函数中panic
语句之后的代码将不再执行。 - 清理defer:当前函数中所有已经注册的
defer
语句会按照后进先出(LIFO)的顺序依次执行。 - 传播至调用者:执行完
defer
后,panic
会传播到调用当前函数的上层函数,上层函数重复上述1、2步骤,即停止执行剩余代码,执行defer
,然后继续向上传播panic
。 - 程序终止:如果
panic
一直传播到main
函数且没有被恢复(通过recover
),程序将异常终止并打印出panic
信息以及调用栈信息。
以下是不同函数嵌套情况下panic
传播路径的示例:
package main
import "fmt"
func funcC() {
panic("panic in funcC")
}
func funcB() {
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered in funcB:", r)
}
}()
funcC()
fmt.Println("This line won't be printed")
}
func funcA() {
funcB()
fmt.Println("This line won't be printed either")
}
func main() {
funcA()
fmt.Println("This line won't be printed")
}
在上述代码中:
funcC
中发生panic
,funcC
内panic
后的代码不再执行。funcC
没有defer
,panic
传播到funcB
。funcB
中funcC
调用之后的代码不再执行,funcB
的defer
执行,由于recover
,panic
在此处被捕获,不会继续传播。funcA
和main
函数中剩余代码正常执行,因为panic
在funcB
中被恢复。
如果在funcB
中没有recover
,panic
将继续传播到funcA
,再到main
,最终导致程序异常终止。