panic+recover golang 中的try catch

一、知识点、1、用到go 关键字定位2、用到defer 延后处理最终执行3、内置函数说明:

image.png

二、代码、、、package main

import ("fmt""time")

func serve(ch <-chan int) {for val := range ch {go handle(val)}}

func handle(x int) {defer func() {if err := recover(); err != nil {fmt.Println("work failed at :", err)}}()

if x == 4 {    panic(x)}fmt.Println("work successed at :", x)

}

func main() {var ch = make(chan int, 6)for i := 1; i <= 6; i++ {ch <- i}close(ch)go serve(ch)time.Sleep(time.Millisecond * 100)}

、、、

三、图片及运行结果

image.png

如何在Golang中,优雅地处理panic?

如何在Golang中,优雅地处理panic?

在文章使用recover捕获panic,请注意这个坑中,我们已经了解了,recover只能恢复同一协程里的panic,而跨协程的panic是无法recover的。这和PHP里的try……catch……很不一样,这也是很多Golang初学者,容易产生疑惑的地方。

既然我们不能跨协程recover所有的panic,那我们如何优雅的处理Golang中的panic呢?

当然,在每一个需要recover的地方都写一遍捕获逻辑,肯定是很麻烦的。另外,从可阅读性来说这也是不好的。比如,像下面这样:

如何在Golang中,优雅地处理panic?

最好的办法是可以将这一段代码封装到一个TryCatch方法里,然后在需要recover的地方,直接调TryCatch方法即可。比如,像下面这样:

如何在Golang中,优雅地处理panic?

其中,coFunc是需要传入的协程方法,这是处理业务的主体方法;errFunc是需要传入的处理错误的方法,也就是recover到的panic。

如何在Golang中,优雅地处理panic?

当我们需要recover可能的panic时,我们就可以直接调TryCatch方法,像上图这样。这样我们就可以成功捕获可能的panic,从而避免了直接crash。

这样的处理方式,不仅简单,而且顾名思义。是不是,也优雅了许多。