go中宕机与恢复 panic/recover 介绍

       

目录

一、panic 宕机

二、recover恢复

三、panic和recover的关系


        Go 语言可以在程序中手动触发宕机,让程序崩溃,这样开发者可以及时地发现错误,同时减少可能的损失。Go 语言程序在宕机时,会将堆栈和 goroutine 信息输出到控制台,所以宕机也可以方便地知晓发生错误的位置.

一、panic 宕机

func panic(v interface{})

panic() 的参数可以是任意类型,后文将提到的 recover 参数会接收从 panic() 中发出的内容。

package main
import "fmt"
func main(){
    
    defer fmt.Println("宕机后要做的事情1")
    defer fmt.Println("宕机后要做的事情2")
    fmt.Println("bb")
    panic("宕机")
    fmt.Println("dd")
    defer func(){
        fmt.Println("ee")
    }()
}

输出

bb
宕机后要做的事情2
宕机后要做的事情1
panic: 宕机
 
goroutine 1 [running]:
main.main()
    /Users/root/Desktop/test.go:9 +0xf1
exit status 2

1、panic() 后面的代码将不会被运行

2、但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用

二、recover恢复

Go 没有异常系统,其使用 panic 触发宕机类似于其他语言的抛出异常,那么 recover 的宕机恢复机制就对应 try/catch 机制。

无论是代码运行错误由 Runtime 层抛出的 panic 崩溃,还是主动触发的 panic 崩溃,都可以配合 defer 和 recover 实现错误捕捉和恢复,让代码在发生崩溃后允许继续运行。

package main
import "fmt"
func main() {
    defer func() {
        if info := recover(); info != nil {
            fmt.Println("触发了宕机", info)
        } else {
            fmt.Println("程序正常退出")
        }
    }()
    
    fmt.Println("bbbbbb")
    fmt.Println("cccccc")
    panic("fatal error")
    fmt.Println("ddddd")
    defer func() {
        fmt.Println("eeeeeeee")
    }()
}

//代码运行
bbbbbb
cccccc
触发了宕机 fatal error

三、panic和recover的关系

panic 和 defer 的组合有如下特性

  • 有 panic 没 recover,程序宕机。
  • 有 panic 也有 recover 捕获,程序不会宕机。执行完对应的 defer 后,从宕机点退出当前函数后继续执行。

1)虽然 panic/recover 能模拟其他语言的异常机制,但并不建议代表编写普通函数也经常性使用这种特性。

2)在 panic 触发的 defer 函数内,可以继续调用 panic,进一步将错误外抛直到程序整体崩溃。

3)如果想在捕获错误时设置当前函数的返回值,可以对返回值使用命名返回值方式直接进行设置。

你可能感兴趣的:(go,宕机,恢复)