panic&recover源码释义

I、panic

1、源码释义:

	The panic built-in function stops normal execution of the current
goroutine. When a function F calls panic, normal execution of F stops
immediately. Any functions whose execution was deferred by F are run in
the usual way, and then F returns to its caller. To the caller G, the
invocation of F then behaves like a call to panic, terminating G's
execution and running any deferred functions. This continues until all
functions in the executing goroutine have stopped, in reverse order. At
that point, the program is terminated with a non-zero exit code. This
termination sequence is called panicking and can be controlled by the
built-in function recover.

翻译过来就是:
panic 内置函数停止当前 goroutine的正常执行。当函数 F 调用 panic 时,F 的正常执行会立即停止。F中的任何defer延迟调用的函数都以常规方式运行,然后 F 返回其调用方。对于调用方 G,F 的调用就像调用panic一样,终止 G 的执行并运行任何defer的函数。这一直持续到执行 goroutine 中的所有函数都以相反的顺序停止。此时,程序以非零退出代码终止。此终止序列称为 panicking ,可通过内置函数 recover 进行控制。
 为了搞清楚defer,panic,和return执行的顺序,来看一个小例子:

2、例子


func main() {
	A()
}

func A() {

	defer func() {
		fmt.Println("defer")
	}()
	fmt.Println("func A")
	panic("panic in A")
	return
}

输出:

func A
defer
panic: panic in A

goroutine 1 [running]:
main.A()
        E:/go/basicGo/basictype/testpanic.go:15 +0x8b
main.main()
        E:/go/basicGo/basictype/testpanic.go:6 +0x17

Process finished with the exit code 2

可以看出程序exit code2,没有正常运行,但是在panic前执行了defer函数,这就是源码释义中的:当函数 F 调用 panic 时,F 的正常执行会立即停止。F中的任何defer延迟调用的函数都以常规方式运行,然后 F 返回其调用方
如果是使用recover函数捕获异常:

func A() {

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("recover:", r)
		}
	}()
	fmt.Println("func A")
	panic("panic in A")
	return
}

输出:

func A
recover: panic in A

Process finished with the exit code 0

exit code 0 程序正常退出,说明panic被revover捕获,那recover(),又是个什么呢:

II、recover

1、源码释义:

The recover built-in function allows a program to manage behavior of a
panicking goroutine. Executing a call to recover inside a deferred
function (but not any function called by it) stops the panicking sequence
by restoring normal execution and retrieves the error value passed to the
call of panic. If recover is called outside the deferred function it will
not stop a panicking sequence. In this case, or when the goroutine is not
panicking, or if the argument supplied to panic was nil, recover returns
nil. Thus the return value from recover reports whether the goroutine is
panicking.

翻译:
内置函数recover 被用来管理 抛出panic的goroutine的行为,把recover()放在defer func(){}中调用,会恢复程序的正常执行,并停止panic序列,而且recover()会捕获panic中抛出的错误信息并且作为其返回值。如果在defer函数之外调用recover,它不会停止panicking 序列。另外,当 goroutine 没有发生panic,或者如果提供给panic的参数为 nil,则 recover 返回 nil。因此,可以通过recover的返回值是否为空来判断goroutine 是否崩溃

2、小例子:

func main() {
	A()
}

func A() {

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("defer in func A catch the err:", r)
		}
	}()
	B()
	fmt.Println("This is func A")
}

func B() {

	C()
	fmt.Println("This is func B")
}

func C() {
	fmt.Println("This is func C")
	panic("panic err in func C")
}

输出:

This is func C
defer in func A catch the err: panic err in func C
This is func main

在这个例子中,A调用B,B调用C,可以看出在func C 中的panic最中在A中被捕获,pancking 在A中被stop,所以调用A的函数都能按照自己本来的方式运行,您也可以尝试在func B 或者func C中捕获panic的err。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值