本文次要钻研一下golang的error加强

Errors in Go 1.13

golang的1.13版本对error进行了加强,次要是

  • 引入了Unwrap办法
  • 减少Is和As办法
  • fmt.Errorf反对%w来包装error

实例

package mainimport (    "errors"    "fmt"    "os")var DemoErr = errors.New("test error stack")// https://itnext.io/golang-error-handling-best-practice-a36f47b0b94cfunc main() {    if err := methodA(false); err != nil {        fmt.Printf("%+v\n", err)    }    if err := methodA(true); err != nil {        fmt.Printf("%+v\n", err)        fmt.Printf("%+v\n", errors.Unwrap(err))        fmt.Printf("%+v\n", errors.Unwrap(errors.Unwrap(err)))        fmt.Println("errors.Is(err, DemoErr)=", errors.Is(err, DemoErr))        fmt.Println("errors.As(err, &DemoErr)=", errors.As(err, &DemoErr))        var pe *os.PathError        fmt.Println("errors.Is(err, pe)=", errors.Is(err, pe))        fmt.Println("errors.As(err, &pe)=", errors.As(err, &pe))    }}func methodA(wrap bool) error {    if err := methodB(wrap); err != nil {        if wrap {            return fmt.Errorf("methodA call methodB error: %w", err)        }        return err    }    return nil}func methodB(wrap bool) error {    if err := methodC(); err != nil {        if wrap {            return fmt.Errorf("methodB call methodC error: %w", err)        }        return err    }    return nil}func methodC() error {    return DemoErr}

输入

test error stackmethodA call methodB error: methodB call methodC error: test error stackmethodB call methodC error: test error stacktest error stackerrors.Is(err, DemoErr)= trueerrors.As(err, &DemoErr)= trueerrors.Is(err, pe)= falseerrors.As(err, &pe)= false

小结

  • wrap对error进行了包装,不过没有蕴含堆栈
  • Is会挨个unwrap去对error进行判断errors.Is function behaves like a comparison to a sentinel error
  • As相似类型断言 errors.As function behaves like a type assertion

doc

  • Errors
  • Working with Errors in Go 1.13
  • Error Handling in Go 1.13
  • Proposal: Go 2 Error Inspection
  • Golang error浅析