• go 错误处理策略


    让我们演示一个文件复制的例子:函数需要打开两个文件,然后将其中一个文件的内容复制到另一个文件:

    func CopyFile(dstName, srcName string) (written int64, err error) {
        src, err := os.Open(srcName)
        if err != nil {
            return
        }
    
        dst, err := os.Create(dstName)
        if err != nil {
            return
        }
    
        written, err = io.Copy(dst, src)
        dst.Close()
        src.Close()
        return
    }
    

    上面的代码虽然能够工作,但是隐藏一个bug。如果第一个os.Open调用成功,但是第二个os.Create调用失败,那么会在没有释放src文件资源的情况下返回。虽然我们可以通过在第二个返回语句前添加src.Close()调用来修复这个BUG;但是当代码变得复杂时,类似的问题将很难被发现和修复。我们可以通过defer语句来确保每个被正常打开的文件都能被正常关闭:

    func CopyFile(dstName, srcName string) (written int64, err error) {
        src, err := os.Open(srcName)
        if err != nil {
            return
        }
        defer src.Close()
    
        dst, err := os.Create(dstName)
        if err != nil {
            return
        }
        defer dst.Close()
    
        return io.Copy(dst, src)
    }
    

    defer语句可以让我们在打开文件时马上思考如何关闭文件。不管函数如何返回,文件关闭语句始终会被执行。同时defer语句可以保证,即使io.Copy发生了异常,文件依然可以安全地关闭。

    前文我们说到,Go语言中的导出函数一般不抛出异常,一个未受控的异常可以看作是程序的BUG。但是对于那些提供类似Web服务的框架而言;它们经常需要接入第三方的中间件。因为第三方的中间件是否存在BUG是否会抛出异常,Web框架本身是不能确定的。为了提高系统的稳定性,Web框架一般会通过recover来防御性地捕获所有处理流程中可能产生的异常,然后将异常转为普通的错误返回。

    让我们以JSON解析器为例,说明recover的使用场景。考虑到JSON解析器的复杂性,即使某个语言解析器目前工作正常,也无法肯定它没有漏洞。因此,当某个异常出现时,我们不会选择让解析器崩溃,而是会将panic异常当作普通的解析错误,并附加额外信息提醒用户报告此错误。

    func ParseJSON(input string) (s *Syntax, err error) {
        defer func() {
            if p := recover(); p != nil {
                err = fmt.Errorf("JSON: internal error: %v", p)
            }
        }()
        // ...parser...
    }
    

    标准库中的json包,在内部递归解析JSON数据的时候如果遇到错误,会通过抛出异常的方式来快速跳出深度嵌套的函数调用,然后由最外一级的接口通过recover捕获panic,然后返回相应的错误信息。

    Go语言库的实现习惯: 即使在包内部使用了panic,但是在导出函数时会被转化为明确的错误值。



  • 相关阅读:
    5. Longest Palindromic Substring
    56. Merge Intervals
    386. Lexicographical Numbers
    42. Trapping Rain Water
    *[topcoder]BracketExpressions
    [codility]CountDiv
    *[codility]MinAvgTwoSlice
    *[codility]MissingInteger
    [mock]7月25日
    网络广告术语
  • 原文地址:https://www.cnblogs.com/ithubb/p/14187895.html
Copyright © 2020-2023  润新知