zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    一天一个设计模式(15)——中介者模式
    一天一个设计模式(14)——迭代器模式
    一天一个设计模式(13)——命令模式
    一天一个设计模式(12)——责任链模式
    一天一个设计模式(11)——代理模式
    《windows程序设计》学习_3.4:实现雷区翻转
    《windows程序设计》学习_3.3:利用xp扫雷资源
    《windows程序设计》学习_3.2:左键的使用
    《windows程序设计》学习_3.1:画出雷区,左键的使用
    《windows程序设计》学习_2.2:初识消息,双键的使用
  • 原文地址:https://www.cnblogs.com/twoheads/p/12845404.html
Copyright © 2011-2022 走看看