首页 > 编程笔记 > Go语言笔记 阅读:21

Go语言recover():恢复程序正常执行(附带实例)

Go语言中,使用 recover() 可以在宕机后让程序继续执行。recover() 是 Go语言的内置函数,该函数可以捕获 panic 信息,类似于其他编程语言中用于捕获异常的 try…catch 语句。recover 通常在使用 defer 语句的函数中执行。

如果当前执行的函数发生 panic,那么调用 recover() 函数可以获取 panic 信息,并且恢复程序正常执行。

示例代码如下:
package main

import "fmt"

func test() {
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println("恢复执行")
    }()
    panic("程序崩溃") // 触发宕机
}

func main() {
    fmt.Println("程序开始")
    test()
    fmt.Println("程序结束")
}
运行结果如下:

程序开始
程序崩溃
恢复执行
程序结束

由运行结果可以看出,通过 recover() 函数可以获取 panic 信息,后面的程序可以正常按顺序执行。

如果 panic() 函数和 recover() 函数一起使用,并且程序中的函数调用比较复杂,则在执行完对应的 defer 语句后,程序退出当前函数并返回到调用处继续执行。代码如下:
package main

import "fmt"

func first() {
    fmt.Println("first 函数开始")
    second()
    fmt.Println("first 函数结束")
}

func second() {
    defer func() { recover() }()
    fmt.Println("second 函数开始")
    third()
    fmt.Println("second 函数结束")
}

func third() {
    fmt.Println("third 函数开始")
    panic("Program crash")  // 触发宕机
    fmt.Println("third 函数结束")
}

func main() {
    fmt.Println("程序开始")
    first()
    fmt.Println(19)
    fmt.Println("程序结束")
}
运行结果为:

程序开始
first 函数开始
second 19开始
Program crash
second 函数结束
first 函数结束
程序结束

由运行结果可以看出,在 third() 函数中触发宕机,程序执行 second() 函数中的 defer 语句,在执行完该语句后退出 second() 函数,并返回调用该函数的 first() 函数继续执行。

注意,虽然 panic() 函数和 recover() 函数可以模拟其他语言的异常机制,但在编写普通函数时不建议使用这种特性。

如果 defer 语句中也存在 panic,那么只有最后一个 panic 可以被 recover() 函数捕获。代码如下:
package main

import "fmt"

func main() {
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println("恢复执行")
    }()
    defer func() {
        panic("defer panic") // 触发宕机
    }()
    panic("panic") // 触发宕机
}
运行结果如下:

defer panic
恢复执行

在上述代码中,当触发程序最后的 panic() 函数时,将触发 defer 语句执行,defer 中的 panic() 函数将覆盖之前的 panic() 函数,并被 recover() 函数捕获。

相关文章