panic解析:
关于panic,接下来主要讲panic的执行机制和顺序,我会通过多个例子来讲解不同情况下panic逻辑的处理流程。
首先这是panic的结构体
与defer是相辅相成的:
首先,通过上一节defer的讲解我们知道,多个defer组成列表挂在当前协程goroutine的成员变量_defer字段下的。
同理在goroutine结构体上还有个字段是用来挂接多个_panic结构体的。
panic与defer的联动
简单例子
func deferA(){
}
//伪代码
func main(){
defer deferA()
panic("MAIN")
}
- 先向当前协程的_defer字段上挂接defer
- 遇到panic,此时向协程的panic字段挂接panic
- 因为遇到了panic,所以程序停止,从而触发panic,而panic也会触发defer方法。
首先我们可以看下_defer结构体:
type _defer struct {
siz int32
started bool //1、panic执行defer,会先将defer的started置为true
sp uintptr
pc uintptr
fn *funcval
_panic *panic// 2、panic字段指向当前执行的panic
link *_defer
}
且panic触发了defer方法,所以对应
_deferA.started=true,
_deferA._panic=panicMAIN
如图
- 最终deferA执行完毕且deferA节点被移除后,协程输出panicMAIN信息。
要明确的是,defer执行完后,所有在panic链表上的项都会被输出,顺序于panic发生的顺序一致。
例子二
承接例子一,如果增加一个defer
func deferA(){
}
func deferB(){
}
//伪代码
func main()