深入理解 Go | panic 和 recover

golang 中使用了以下两个内置函数来处理错误和恢复:

func panic(v interface{})

  • 一旦调用:
    • 立刻停止执行函数其他代码
    • 执行结束后,在当前 Goroutine 中递归执行调用方的延迟函数调用 defer
  • 允许在 defer 中嵌套多次调用

func recover() interface{}

  • 用于中止 panic 造成的程序崩溃
  • 只能在 defer 中发挥作用(只有在 panic 之后调用才生效)

基于 Go 1.14

数据结构

panic 关键字在 golang 中由数据结构 runtime._panic 表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// A _panic holds information about an active panic.
//
// This is marked go:notinheap because _panic values must only ever
// live on the stack.
//
// The argp and link fields are stack pointers, but don't need special
// handling during stack growth: because they are pointer-typed and
// _panic values only live on the stack, regular stack pointer
// adjustment takes care of them.
//
//go:notinheap
type _panic struct {
argp unsafe.Pointer // 指向 panic 期间运行的 defer 调用的参数
arg interface{} // 调用 panic 时传入的参数
link *_panic // 指向更早调用的 panic
pc uintptr // where to return to in runtime if this panic is bypassed
sp unsafe.Pointer // where to return to in runtime if this panic is bypassed
recovered bool // 表示当前这个 panic 是否被 recover 恢复
aborted bool // 表示当前这个 panic 是否被强行终止
goexit bool // 当调用了 runtime.Goexit(),就会将该值修改为 true
}

编译时



运行时



请言小午吃个甜筒~~