zoukankan      html  css  js  c++  java
  • Golang的异常处理实战篇

              Golang的异常处理实战篇

                                 作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

     

     

      Go语言的异常捕获要比Python中简单的多,它没有Python中那么多复杂的异常类型及继承体系。接下来我们来一起体验一下Golang的异常处理。

     

     

    一.代码运行时出错应该怎样处理呢?

    1>.算数除零异常案例

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        //定义除数
        a := 20
    
        //定义被除数
        b := 0
    
        //除数不能为0,编译时并不会报错,但是在代码运行时会报错哟~
        c := a / b
    
        //由于上面的代码执行报错啦,该行代码不会被执行
        fmt.Printf(" %d ➗ %d = %d
    ", a, b, c)
    }

    2>.数组索引越界异常案例

    package main
    
    import (
        "fmt"
    )
    
    func myArr(index int) {
    
        //定义数组
        var arr [10]int
    
        //数组这里赋值时可能会存在一个风险,即索引越界异常
        arr[index] = 123
    
        fmt.Println(arr)
    }
    
    func main() {
        myArr(12)
    }

    二.Go语言中自定义异常接口

    1>.使用errors自定义异常消息(并不会使得程序崩溃)

    package main
    
    import (
        "errors"
        "fmt"
    )
    
    func div(x int, y int) (res int, err error) {
    
        if y == 0 {
            /*
                Go语言引入了一个关于错误处理的标准模式,即error接口,该接口需要导入"errors"包:
                    errors接口适合返回可控的错误,即我们知道在某个代码块中可能会出现的异常。
            */
            err = errors.New("div函数除零异常...")
            return
        }
        res = x / y
        return
    }
    
    func main() {
        a := 10
        b := 0
    
        /*
            res:
                用来接收运算结果
            err:
                用来接收错误消息
            nil:
                表示空,"if err != nil"表示变量err接收的错误消息是否为空。
        */
        res, err := div(a, b)
        if err != nil {
            fmt.Println(err)
            //log.Fatal(err) //我们也可以使用log包来帮助咱们输出错误,它会在错误消息签名自动加上日期时间
        } else {
            fmt.Println(res)
        }
    
        fmt.Println("代码执行完毕")
    }

    2>.使用panic自定义异常消息(程序会崩溃)

    package main
    
    import (
        "fmt"
    )
    
    func myArr2(index int) {
    
        //定义数组
        var arr [10]int
    
        if index >= 10 {
            /*
                panic函数与errors接口不同:
                    (1)使用panic时无需导入包;
                    (2)若出现异常,使用panic封装异常消息时,会直接导致程序运行结束,换句话说,error是一般性错误,而panic函数返回的是让程序崩溃的错误
    
                温馨提示:
                    一般而言,当panic异常发生时,程序会中断运行。随后,程序崩溃并输出日志消息。日志信息包括panic value和函数调用的堆栈跟踪信息
                    当然,如果直接调用内置的panic函数也会引发panic异常,panic函数接收任何值作为参数。
            */
            panic("请注意,index > 10,出现了索引越界异常...(index的取值范围0~9)")
        }
    
        //上面使用了panic接口封装了异常处理错误,因此如果代码到这一行说明没有索引越界异常
        arr[index] = 123
        fmt.Println(arr)
    }
    
    func main() {
    
        myArr2(12)
    
        fmt.Println("代码执行完毕")
    }

    三.使用recover进行异常捕获

    1>.defer延迟调用

    package main
    
    import (
        "fmt"
    )
    
    func main() {
    
        /*
            defer语句被用于预定对一个函数的调用。可以把这类被defer语句调用的函数称为函数。
    
            defer的应用场景:
                (1)释放占用的资源;
                (2)捕获异常处理
                (3)输出日志
    
            温馨提示:
                如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行。
    
            先不要运行代码,你先猜猜下面的代码的执行顺序。
        */
        defer fmt.Println("	https://www.cnblogs.com/yinzhengjie/")
    
        fmt.Println("我的名字叫尹正杰,英文名叫'Jason Yin'.爱好开源技术.")
    
        defer fmt.Println("	https://www.cnblogs.com/yinzhengjie2020")
    
        fmt.Println("我的博客是:")
    }

    2>.defer结合recover进行错误拦截

    package main
    
    import "fmt"
    
    func test3(index int) {
        /*
            错误拦截要在产生错误前设置,因此建议大家把错误拦截的函数放在函数内部的首行定义。
        */
        defer func() {
            /*
                运行时panic异常一旦被引发就会导致程序崩溃
                Go语言提供了专用于"拦截"运行时panic的内建函数"recover"。
                它可以使当前的程序从运行时panic的状态中恢复并重新获得流程控制权,欢聚话说,通过recover进行不可控的错误拦截,重新获取程序的控制权
            */
            err := recover()
            if err != nil {
                fmt.Println(err)
            }
        }()
    
        /*
            定义容量为10的数组
        */
        var arr [10]int
    
        if index >= 10 {
            panic("请注意,index > 10,出现了索引越界异常...(index的取值范围0~9)")
        }
    
        arr[index] = 123
    
        fmt.Println(arr)
    }
    
    func main() {
        test3(5)
        test3(12)
        fmt.Println("代码执行完毕")
    }

     3>.面试题(请根据下面代码手写出输出结果)

    package main
    
    import (
        "fmt"
    )
    
    func f1() (int, error) {
        defer fmt.Println(1)
        defer fmt.Println(2)
        fmt.Println(3)
        return fmt.Println(4)
    }
    
    func f2() (int, error) {
        defer fmt.Println(5)
        defer fmt.Println(6)
        fmt.Println(7)
        f1()
    
        defer func() (int, error) {
            defer fmt.Println(8)
            fmt.Println(9)
            return fmt.Println(10)
        }()
    
        return fmt.Println(11)
    }
    
    func main() {
        f2()
    }

  • 相关阅读:
    计算机网络(1)----概述
    博客园自定义样式
    linux进程
    接口回调解析
    优先级队列
    双栈实现队列
    递归解决反转链表的一部分
    Multisim 之逻辑转换仪
    Multisim 如何添加文本 如何编辑文本字体
    Multisim 中的一些快捷键
  • 原文地址:https://www.cnblogs.com/yinzhengjie2020/p/12324684.html
Copyright © 2011-2022 走看看