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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

panic 是基于goroutine级别的异常机制,即是说,如果你程序里的 panic 的产生跨多个 goroutine 时,那么此时你想 catch 住该 panic ,一定在 panic 产生的同一个 goroutine 里进行捕获,否则无效。

同一个goroutine javaer可以理解为同一个线程内

一、简单使用

1.1 同一个goroutine

!Pasted image 20231202224619.png

1.2 跨goroutine

!Pasted image 20231202224733.png 调用链关系未变,但 func2func3 在不同的 goroutine 中,那么这时候在 func1 中是无法捕获到后续子协程的 panic 异常,而且,这种子协程的 panic 如果未有效拦截,也会导致主进程崩溃,所以不得不重视它。 所以,但凡你要新启一个 goroutine,而你又不完全确定是否它会产生 panic ,那么保险的做法在启动的时候进行拦截,做到 "谁创建,谁负责" 的原则。

!Pasted image 20231202224859.png

二、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没有好的解决办法。