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.

61 lines
2.0 KiB

2 years ago
**panic 是基于goroutine级别的异常机制**,即是说,如果你程序里的 `panic` 的产生跨多个 `goroutine` 时,那么此时你想 `catch` 住该 `panic` ,一定在 `panic` 产生的同一个 `goroutine` 里进行捕获,否则无效。
同一个`goroutine` javaer可以理解为同一个线程内
# 一、简单使用
## 1.1 同一个goroutine
![[Pasted image 20231202224619.png]]
## 1.2 跨goroutine
![[Pasted image 20231202224733.png]]
调用链关系未变,但 `func2`、`func3` 在不同的 `goroutine` 中,那么这时候在 `func1` 中是无法捕获到后续子协程的 `panic` 异常,**而且,这种子协程的 `panic` 如果未有效拦截,也会导致主进程崩溃,所以不得不重视它。**
所以,但凡你要新启一个 `goroutine`,而你又不完全确定是否它会产生 `panic` ,那么保险的做法在启动的时候进行拦截,做到 "谁创建,谁负责" 的原则。
![[Pasted image 20231202224859.png]]
# 二、panic和直接返回error
这个问题有不少争论估计go2官方会出新的异常处理语法先来对比下两种方式
+ error
```go
// 使用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
```go
// 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没有好的解决办法。