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?
在文章使用recover捕获panic,请注意这个坑中,我们已经了解了,recover只能恢复同一协程里的panic,而跨协程的panic是无法recover的。这和PHP里的try……catch……很不一样,这也是很多Golang初学者,容易产生疑惑的地方。
既然我们不能跨协程recover所有的panic,那我们如何优雅的处理Golang中的panic呢?
当然,在每一个需要recover的地方都写一遍捕获逻辑,肯定是很麻烦的。另外,从可阅读性来说这也是不好的。比如,像下面这样:
最好的办法是可以将这一段代码封装到一个TryCatch方法里,然后在需要recover的地方,直接调TryCatch方法即可。比如,像下面这样:
其中,coFunc是需要传入的协程方法,这是处理业务的主体方法;errFunc是需要传入的处理错误的方法,也就是recover到的panic。
当我们需要recover可能的panic时,我们就可以直接调TryCatch方法,像上图这样。这样我们就可以成功捕获可能的panic,从而避免了直接crash。
这样的处理方式,不仅简单,而且顾名思义。是不是,也优雅了许多。