• Go异常处理


    首先很抱歉,由于搬家,最近太多事情要处理,导致文章更新比较慢。

    这篇文章,我们讲Go中的异常处理。

    Go提供了两个内置函数 panic()和recover()用于异常处理。

    Go中,对异常处理的整体原则是:多用errors包,少用panic。

    对于可预见的错误,比如网络连接失败等,一般都使用errors,只有重大错误才会使用panic。

    记住一个大原则:panic会导致程序直接挂掉,除非调用了recover方法。

    在函数内部调用 panic 会立即终止当前函数的执行,由当前调用栈逐层返回,一直到最顶层的 main 函数或是被某一层的 recover 捕捉到。

    看例子:

    package main

    import (

    "fmt"

    )

    func main() {

    fmt.Println("Start main")

    sub()

    fmt.Println("End main")

    }

    func sub() {

    fmt.Println("Before panic")

    panic("golang_everyday")

    fmt.Println("After panic")

    }

    执行结果:

    Start main

    Before panic

    panic: golang_everyday

     

    goroutine 1 [running]:

    main.sub()

    /Users/baiyuxiong/go/src/baiyuxiong.com/demo/panic.go:18 +0x124

    main.main()

    /Users/baiyuxiong/go/src/baiyuxiong.com/demo/panic.go:10 +0xdf

     

    goroutine 2 [runnable]:

    runtime.forcegchelper()

    /usr/local/go/src/runtime/proc.go:90

    runtime.goexit()

    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

     

    goroutine 3 [runnable]:

    runtime.bgsweep()

    /usr/local/go/src/runtime/mgc0.go:82

    runtime.goexit()

    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

     

    goroutine 4 [runnable]:

    runtime.runfinq()

    /usr/local/go/src/runtime/malloc.go:712

    runtime.goexit()

    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

    exit status 2

    可以看到,panic之后,程序停止继续执行,一层层的退出直到main,退出了整个程序,然后打印了堆栈信息。

    如果我们在sub函数中,使用defer进行recover:

    package main
    
     
    
    import (
    
    "fmt"
    
    )
    
     
    
    func main() {
    
    fmt.Println("Start main")
    
    sub()
    
    fmt.Println("End main")
    
    }
    
     
    
    func sub() {
    
    defer handler()
    
     
    
    fmt.Println("Before panic")
    
    panic("golang_everyday")
    
    fmt.Println("After panic")
    
    }
    
     
    
    func handler() {
    
    if err := recover(); err != nil {
    
    fmt.Println("recover msg: ", err)
    
    } else {
    
    fmt.Println("recover ok")
    
    }
    
    }

    执行结果:

    Start main

    Before panic

    recover msg: golang_everyday

    End main

    可以看到,sub函数没有执行完,panic后执行了defer就返回到上层main函数了,但是main函数执行结束了。

    这是因为recover阻止了异常的继续传播。他将panic限制在了一定的范围内。

    这就像屋子里丢了一炸弹(panic产生了),本来所有人都要挂掉的(panic传递到main,整个程序退出),但是有一个叫recover的小伙子非常勇敢,duang!!!抱到炸弹上去了,损失就控制在一定范围内了,如果这小伙子越早的抱到炸弹,受伤的人就会越少。

  • 相关阅读:
    2008年6月6日今天终于调回公司本部啦,记录历史的一天。
    动易安全开发手册
    今天开机后发现有些图标变了样(图标变灰色),可是功能都能用
    用CFile类简单读写文件
    【转】动态链接库的静态链接导致程序的DLL劫持漏洞借助QQ程序xGraphic32.dll描述
    失败的人只有一种,就是在抵达成功之前放弃的人
    ListControl
    [转贴]仅通过崩溃地址找出源代码的出错行
    tinyxml文档
    得到程序当前UAC的执行权限,高 中 低
  • 原文地址:https://www.cnblogs.com/baiyuxiong/p/4770980.html
Copyright © 2020-2023  润新知