序
本文次要钻研一下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浅析