error和panic,初识Golang的错误和异常处理机制

 说是初识,并不是说第一次使用error和panic包,而是第一次特地去了解golang中的这两个机制。之前写代码一直追求达到目的就可以,很少静下心了解一门语言。需要就用,用过就丢。但是这几天由于没有任务,投出去的简历估计是石沉大海,杳无音讯了。这反而让我可以静下心来把每一个自己感兴趣的点了解清楚,甚至开始研究他的实现,写博客也只是为了让自己加深下理解,如果能帮助到别人那更是上天眷顾(如果我写错了,我感到十分抱歉,并十分感谢你们可以提出来或者帮我指引指引方向^_^),这种感觉还是很不错的,哈哈。
 好吧,以上全是废话。
 首先Golang中错误和异常是两个完全不同的概念。
 大部分错误被认为是可以预期的,所以我们的程序中很多见类似`err := func()`这样的语句,对于这种模式肯定会相对麻烦,但是我觉得会使程序更加健壮,更加易于编程,就好像我们写的API接口,不管有没有取到数据,你要告诉我一个状态,如果出错了,出错的原因是什么。
 而异常则是指:程序在运行时会捕获很多错误,这些错误大多是不可预期的,而这些错误会引发异常。一般来说,一旦异常发生,会导致程序停止运行,并立即执行defer函数中的内容,然后输出错误信息。
 错误处理的方式有五种:
 第一种是如果在子函数中发生错误,那么就应该返回给调用它的函数处理。可以选择直接将错误返回给调用函数,如果子函数中还需要添加一些错误的上下文信息,也可以使用fmt.Errorf()来构建一个包含更多信息的错误返回。
 第二种如果错误是偶然发生的,比如我这个函数需要执行网络链接,不巧执行的时候网络刚好断了几秒,那这种错误我就可以通过多次执行跳过这种错误。
 第三种如果错误发生后,程序无法继续运行,那我们可以输出错误信息并结束程序。需要注意的是,这种策略只应在main中执行。对库函数而言,应仅向上传播错误,除非该错误意味着程序内部包含不一致性,即遇到了bug,才能在库函数中结束程序。
 第四种如果错误发生并不会影响程序大部分功能的执行,那么我们只需要通过log.Printf()函数来打印错误就可以了。
 第五种有些无关紧要的错误,我们可以直接忽略,在函数运行返回值的时候用"_"代替error类型的返回值。
 对于异常的处理相对情况就没有这么复杂了,因为panic是比较严重,不可预期的错误,所以Golang还是不鼓励我们过多使用panic的,如果可能应该使用错误机制来处理这些错误,这也会使我们的程序更加健壮。
 如果程序一定要panic,我们又要对这次panic做一些处理,将程序从崩溃边缘拉回来的话,可以使用deferred函数中调用了内置函数recover。以下是《Go语言圣经》中的例子:
func soleTitle(doc *html.Node) (title string, err error) {
    type bailout struct{}
    defer func() {
        switch p := recover(); p {
        case nil:
        // no panic
        case bailout{}:
        // "expected" panic
            err = fmt.Errorf("multiple title elements")
        default:
            panic(p) // unexpected panic; carry on panicking
        }
    }()
    // Bail out of recursion if we find more than one nonempty title.
    forEachNode(doc, func(n *html.Node) {
        if n.Type == html.ElementNode && n.Data == "title" &&
            n.FirstChild != nil {
            if title != "" {
                panic(bailout{}) // multiple titleelements
            }
            title = n.FirstChild.Data
        }
    }, nil)
    if title == "" {
        return "", fmt.Errorf("no title element")
    }
    return title, nil
}

我们可以看到对于panic我们可以做有选择的恢复,通过recover内置函数可以获取panic value(就是panic函数调用是括号里的参数),如果panic是传入字面值为”bailout{}”, 那么我们就返回一个错误,如果panic没传入字面值我们就不返回也不处理,相当于忽视掉这次panic,当然这要看具体情况来定。剩下那种情况,执行panic相当于我们的defer什么也没做。

以上是Golang的错误和异常处理机制的处理策略,但是没有实例我们只领会他的意思肯定有些抽象,在《GO实战圣经》中5.4, 5.8,5.9,5.10是介绍的这部分内容,大家也可以去参考里边的例子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值