Panic是指程序遇到了(或者由程序主动发起)运行时错误,此时,程序中的函数会立即停止执行,然后执行已经defer过的函数,随后,程序输出错误日志信息,停止运行。

panic函数

当程序出现不可预料的结果的时候,可以通过panic函数引发异常。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func main() {
	defer func() {
		fmt.Println("defer before") //defer before
	}()
	fmt.Println("before call") //before call
	raisePanic()
	defer func() {
		fmt.Println("defer after")
	}()
	fmt.Println("after call")
}

func raisePanic() {
	/*
		发生异常: panic
		"panic"
		Stack:
			2  0x0000000000e02c87 in main.raisePanic
				at {MyPath}/main.go:18
			3  0x0000000000e02b65 in main.main
				at {MyPath}/main.go:10
	*/
	panic("panic")
	fmt.Println("after panic")
}

可见,当panic发生时,函数后续的逻辑以及未defer的逻辑都不会执行。

recover函数

recover函数可以捕获panic,只能在defer函数中执行,毕竟,发生panic时只有defer函数中的逻辑还会继续执行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func main() {
	defer func() {
		if p := recover(); p != nil {
			fmt.Printf("recover from panic, message:%v\n", p)
		}
	}()
	fmt.Println("before call") //before call
	raisePanic()
	defer func() {
		fmt.Println("defer after") //defer after
	}()
	fmt.Println("after call") //after call
}

func raisePanic() {
	defer func() {
		if p := recover(); p != nil {
			fmt.Printf("recover from panic, message:%v\n", p) //recover from panic, message:panic
		}
	}()
	panic("panic")
	fmt.Println("after panic")
}

当panic被recover后,其影响就不会继续向上传递,但是发生panic的函数,其后续逻辑仍然是不会执行。

BGM