Go 的错误处理哲学是"显式胜过隐式"。每个可能失败的操作都返回一个 error,调用者必须显式地处理它。这种看似繁琐的方式实际上能产生更健壮的代码。
Error 接口
Go 的 error 是最简单的接口之一,只有一个 Error() 方法。这种极简设计让定义和使用错误变得异常灵活:
type error interface {
Error() string
}
错误包装
Go 1.13 引入了错误包装机制:
- fmt.Errorf("%w", err):包装错误,保留原始错误。
- errors.Is(err, target):判断错误链中是否包含指定错误。
- errors.As(err, &target):从错误链中提取指定类型的错误。
错误处理模式
- 在边界处(API、数据库操作)创建清晰的错误。
- 在中间层添加上下文信息后向上传递。
- 只在最顶层处理错误(记录日志、返回给用户)。
- 不要同时记录日志和返回错误——要么处理,要么传递。
Go 的错误处理虽然看起来朴素,但却迫使程序员正视每一个可能的失败路径。