• Go 1.13 errors 基本用法


    核心思想:套娃

    啥意思呢?这玩意就像套娃一样,从上往下扒,拿走一个还有一个,再拿走一个,诶还有一个,如果你愿意,可以一直扒到最底下没有了为止。

    基本用法

    1. 创建一个被包装的 error

    方式一:fmt.Errorf

    使用 %w 参数返回一个被包装的 error

    err1 := errors.New("new error")
    err2 := fmt.Errorf("err2: [%w]", err1)
    err3 := fmt.Errorf("err3: [%w]", err2)
    fmt.Println(err3)
    // output
    err3: [err2: [new error]]

    err2 就是一个合法的被包装的 error,同样地,err3 也是一个被包装的 error,如此可以一直套下去。

    方式二:自定义 struct

    type WarpError struct {
        msg string
        err error
    }
    
    func (e *WarpError) Error() string {
        return e.msg
    }
    
    func (e *WrapError) Unwrap() error {
        return e.err
    }

    之前看过源码的同学可能已经知道了,这就是 fmt/errors.go 中关于 warp 的结构。
    就,很简单。自定义一个实现了 Unwrap 方法的 struct 就可以了。

    2. 拆开一个被包装的 error

    errors.Unwrap

    err1 := errors.New("new error")
    err2 := fmt.Errorf("err2: [%w]", err1)
    err3 := fmt.Errorf("err3: [%w]", err2)
    
    fmt.Println(errors.Unwrap(err3))
    fmt.Println(errors.Unwrap(errors.Unwrap(err3)))
    // output
    err2: [new error]
    new error

    3. 判断被包装的 error 是否是包含指定错误

    errors.Is

    当多层调用返回的错误被一次次地包装起来,我们在调用链上游拿到的错误如何判断是否是底层的某个错误呢?
    它递归调用 Unwrap 并判断每一层的 err 是否相等,如果有任何一层 err 和传入的目标错误相等,则返回 true。

    err1 := errors.New("new error")
    err2 := fmt.Errorf("err2: [%w]", err1)
    err3 := fmt.Errorf("err3: [%w]", err2)
    
    fmt.Println(errors.Is(err3, err2))
    fmt.Println(errors.Is(err3, err1))
    // output
    true
    true

    4. 提取指定类型的错误

    errors.As

    这个和上面的 errors.Is 大体上是一样的,区别在于 Is 是严格判断相等,即两个 error 是否相等。
    而 As 则是判断类型是否相同,并提取第一个符合目标类型的错误,用来统一处理某一类错误。

    type ErrorString struct {
        s string
    }
    
    func (e *ErrorString) Error() string {
        return e.s
    }
    
    var targetErr *ErrorString
    err := fmt.Errorf("new error:[%w]", &ErrorString{s:"target err"})
    fmt.Println(errors.As(err, &targetErr))
    // output
    true

    扩展

    Is As 两个方法已经预留了口子,可以由自定义的 error struct 实现并覆盖调用。

    https://segmentfault.com/a/1190000020398774

  • 相关阅读:
    print流
    java数据流
    java转换流
    爬虫(二):urllib库文件的基础和进阶(python2.7)
    爬虫实例(二):多线程,多进程对网页的爬取
    Java多线程分析 (二)---- 高并发内存模型和线程安全
    Java多线程分析 (五)---高并发线程池
    Java 多线程分析 (四) ---高并发基础知识)
    Java(生产者与消费者方法)
    Java 多线程分析 (三) --- synchronize 同步
  • 原文地址:https://www.cnblogs.com/twoheads/p/12845404.html
Copyright © 2020-2023  润新知