You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.0 KiB
2.0 KiB
panic 是基于goroutine级别的异常机制,即是说,如果你程序里的 panic
的产生跨多个 goroutine
时,那么此时你想 catch
住该 panic
,一定在 panic
产生的同一个 goroutine
里进行捕获,否则无效。
同一个goroutine
javaer可以理解为同一个线程内
一、简单使用
1.1 同一个goroutine
1.2 跨goroutine
!
调用链关系未变,但
func2
、func3
在不同的 goroutine
中,那么这时候在 func1
中是无法捕获到后续子协程的 panic
异常,而且,这种子协程的 panic
如果未有效拦截,也会导致主进程崩溃,所以不得不重视它。
所以,但凡你要新启一个 goroutine
,而你又不完全确定是否它会产生 panic
,那么保险的做法在启动的时候进行拦截,做到 "谁创建,谁负责" 的原则。
二、panic和直接返回error
这个问题有不少争论,估计go2官方会出新的异常处理语法,先来对比下两种方式:
- error
// 使用error的写法
func first() error {return nil}
func second() error {return nil}
func third() error {return nil}
func fourth() error {return nil}
func fifth() error {return nil}
func Do() error {
var err error
if err = first(); err == nil {
if err = second(); err == nil {
if err = third(); err == nil {
if err = fourth(); err == nil {
if err = fifth(); err == nil {
return nil
}
}
}
}
}
return err
}
- panic
// panic 写法
func Do2() (err error) {
defer func(){
if r:= recover() ; r!= nil{
err = fmt.Errorf("Error: %+v", r)
}
}()
first2()
second2()
third2()
fourth2()
fifth2()
return
}
存在多层次的调用,问题在于如何准确定位异常位置,目前go没有好的解决办法。