zoukankan      html  css  js  c++  java
  • 9.8Go之函数之宕机恢复(recover)

    9.8Go之函数之宕机恢复(recover)

    recover的概念

    • Recover 是一个Go语言的内建函数,可以让进入宕机流程中的 goroutine 恢复过来

    特点:

    • recover 仅在延迟函数 defer 中有效,在正常的执行过程中,调用 recover 会返回 nil 并且没有其他任何效果

    • 如果当前goroutine发生异常,调用recover可以捕获panic的输入值,且恢复正常的执行

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

    panic和recover之间的关系

    • 有 panic 没 recover,程序宕机。

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

    其他语言的异常处理机制的目的

    以Java中的异常处理机制为例:

    • 底层抛出异常,上层逻辑通过 try/catch 机制捕获异常

    • 没有被捕获的严重异常会导致宕机,捕获的异常可以被忽略,让代码继续运行。

    本质就是希望通过捕获异常的方式让程序继续运行下去

    让程序在崩溃时继续运行示例

    需求:

    • 实现一个Run函数

      • 传入一个匿名函数或闭包后的执行函数--->形参

    • 传入函数以任何形式发生 panic 崩溃后,可以将崩溃发生的错误打印出来

    • 同时允许后面的代码继续运行,不会造成整个进程的崩溃。

    package main

    import (
    "fmt"
    "runtime"
    )

    /*
    定义一个结构体,里面的元素定义为抛出异常时需要传递的上下文信息
    */
    type panicContent struct {
    function string //当前所在函数
    }
    /*
    声明描述错误的结构体,保存执行错误的函数。
    */

    /*
    实现一个run函数,形参为一个函数或者是闭包
    */
    func Run(entry func()) {
    //defer标记宕机处理
    defer func() { //--->非常重要:defer 将闭包延迟执行,当 panic 触发崩溃时,Run() 函数将结束运行,此时 defer 后的闭包将会发生调用
    //发生宕机时,获取panic传递的上下文并打印
    err := recover() //recover() 获取到 panic 传入的参数

    switch err.(type) { //错误类型断言
    case runtime.Error:
    //运行时异常
    fmt.Println("runtime Error:", err)
    default:
    fmt.Println("another unknow Error:", err)
    }
    }()

    entry()
    }

    func main() {
    fmt.Println("运行前:")

    //调用run函数,手动触发错误
    Run(func() {
    fmt.Println("手动触发宕机前:")

    //使用panic结构体传递上下文--->一个指针对象,指向结构体
    panic(&panicContent{ //--->这是将一个结构体附带信息传递给panic
    "手动触发panic",
    /*
    使用 panic 手动触发一个错误,并将一个结构体附带信息传递过去
    recover 就会获取到这个结构体信息,并打印出来
    */
    })

    fmt.Println("手动触发宕机后。")
    })
    /*
    这不是一个运行时异常,宕机被恢复了,所以可以执行下面一个空指针错误的方法
    */

    //手动触发空指针错误
    Run(func() {
    fmt.Println("赋值宕机前:")

    var a *int
    *a = 1
    /*
    模拟代码中空指针赋值造成的错误
    由 Runtime 层抛出错误,被 Run() 函数的 recover() 函数捕获到
    */

    fmt.Println("赋值宕机后。")
    })
    /*
    这是一个运行时异常
    */

    fmt.Println("运行后。")
    }

    代码分析:

    • defer标记的函数--->panic触发崩溃run函数即将结束才会执行

    • panic--->可以将一个结构体传递给panic,通过指针传递,并且附带内容。panic获取到以后直接会打印里面的内容

    • 空指针错误被抛出会在run函数结束前由recover函数捕获到然后让程序继续往下执行--->不会退出

  • 相关阅读:
    mac iterm2 安装 lrzsz rz sz命令
    bash rz 上传文件失败问题
    vue-router scrollBehavior无效的问题及解决方案
    dependencies devDependencies peerDependencies optionalDependencies区别
    Nuxt / Vue.js in TypeScript: Object literal may only specify known properties, but 'components' does not exist in type 'VueClass'
    NodeJS中的require和import
    Git fetch和git pull的区别, 解决Git报错:error: You have not concluded your merge (MERGE_HEAD exists).
    webstorm打开带有node_modules文件夹的工程时很卡
    CSS3自定义滚动条样式 -webkit-scrollbar
    nginx 中location和root、alias
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/15244307.html
Copyright © 2011-2022 走看看