go:recover()

148 阅读1分钟

参考网址

blog.csdn.net/nexttrial/a…

前言

go语言中,如果我们的函数或者程序出现了很严重的问题,或者说我们的程序遇到了panic异常,
此时我们的程序就会终止运行。

但是,我们并不想程序终止运行,而是希望当程序遇到问题时,我们的程序可以做一些处理,保证程序可以正常的运行。
那么这时候,我们就需要使用异常恢复,即recover.
golang中的recover,一般是和defer语句一起使用。

demo

defer func() {
   if r := recover(); r != nil {
      log.Println("revoered in f", r)
   }
}

panic和recover使用原则:

> 1.  defer 需要放在 panic 之前定义,另外 recover 只有在 defer 调用的函数中才有效。
> 1.  recover 处理异常后,逻辑并不会恢复到 panic 那个点去,函数跑到 defer 之后的那个点。
> 1.  多个 defer 会形成 defer 栈,后定义的 defer 语句会被最先调用

panic与recover的关系:

如果有 panic 但没有 recover,那么程序会宕机。
如果有 panic 也有 recover,程序不会宕机,执行完对应的 defer 后,从宕机点退出当前函数后继续执行。
虽然 panic/recover 能模拟其他语言的异常机制,但并不建议在编写普通函数时也经常性使用这种特性。
在 panic 触发的 defer 函数内,可以继续调用 panic,进一步将错误外抛,直到程序整体崩溃。

recover捕获异常

package main
import (
    "fmt"
    "time"
)
func main() {
    f()
    fmt.Println("end")
}

func f() {
    defer func() {
        fmt.Println("defer start")
        if err := recover(); err != nil {
               fmt.Println(err)
        }
        fmt.Println("defer end")
    }()
    
    for {
        fmt.Println("func begin")
        a := []string{"a", "b"}
        fmt.Println(a[3]) // 执行到这里的时候,会报错
        fmt.Println("func end")  // recover()之后,接着执行
        time.Sleep(1 * time.Second)
    }
}