在 Go 语言里,哪些情况会引发 panic 异常?
考察说明
考查对 Go 语言 panic 触发机制的理解与掌握。
回答思路
- 【回答框架 1】Go 语言中 panic 是运行时异常,由程序主动或运行时错误触发。主动触发通过调用内置函数 panic(interface{}),传入任意值作为异常信息。
- 【回答框架 2】运行时错误触发包括:数组或切片越界访问、空指针解引用、向已关闭的 channel 发送数据、类型断言失败(未使用逗号 ok 形式)、调用 nil 指针的方法、整数除以零(编译期可检测,运行时不会触发 panic 而是编译错误)、map 并发读写(检测到并发读写时触发 fatal error,本质是 panic)。
- 【回答框架 3】此外,调用 runtime.Goexit 不会触发 panic,但会终止当前 goroutine;调用 os.Exit 会直接退出进程,不触发 panic。
- 【回答框架 4】panic 会沿调用栈向上传播,逐层执行 defer 函数,直到被 recover 捕获或程序崩溃。recover 只能在 defer 函数中有效,用于恢复 panic 并获取 panic 值。
- 【回答框架 5】常见触发场景还包括:调用不存在的 map 键不会 panic,返回零值;向 nil channel 发送或接收会永久阻塞,不触发 panic。
- 【关键点 1】主动调用 panic 函数可触发异常
- 【关键点 2】数组越界、空指针解引用、向已关闭 channel 发送数据、类型断言失败等运行时错误会触发 panic
- 【关键点 3】panic 会执行 defer 后向上传播,recover 可捕获
- 【关键点 4】map 并发读写会触发 fatal error 即 panic
- 【关键点 5】整数除以零是编译错误,不会在运行时触发 panic
- 【易错点 1】误认为向 nil channel 操作会 panic,实际是阻塞
- 【易错点 2】误认为 recover 可捕获所有异常,但无法捕获 fatal error 如并发读写 map
- 【易错点 3】误认为 panic 后程序一定崩溃,recover 可恢复