Go语言基础:错误处理

1. 错误处理基础

Go语言通过`error`接口实现错误处理,标准库函数通常返回`(结果, error)`格式。当`error`为`nil`时表示操作成功,非`nil`时表示出错:

示例:基础错误返回

关键点说明:

  • `error`接口定义:`type error interface { Error() string }`
  • 优先使用`errors.New`创建简单错误
  • 避免忽略错误(使用`_`占位符时需明确意图)

2. 自定义错误类型

通过实现`error`接口可以创建自定义错误类型,携带更多错误信息(如错误码、调用栈等):

示例:自定义错误类型

设计优势:

  • 可以携带结构化错误信息(错误码、上下文等)
  • 通过类型断言区分不同错误类型
  • 支持更精细的错误处理逻辑

3. defer与recover

`defer`语句用于延迟执行函数(通常用于资源清理),`recover`用于捕获`panic`(运行时错误)并恢复程序:

示例:defer与recover使用

使用原则:

  • `defer`语句按后进先出顺序执行
  • `recover`只能在`defer`函数中有效
  • 避免滥用`panic`(仅用于不可恢复的错误)

4. 错误传播与包装

通过`fmt.Errorf`的`%w`动词可以包装错误,保留原始错误信息,便于上层调用链追踪:

示例:错误包装与解包

关键函数:

  • `errors.Is(err, target)`:判断错误链中是否包含目标错误
  • `errors.As(err, target)`:将错误链中的第一个匹配类型的错误赋值给target
  • `fmt.Errorf("... %w ...", err)`:创建可包装的错误

5. 最佳实践

Go语言错误处理的推荐实践:

  • 优先返回`error`而不是使用`panic`(`panic`应仅用于程序无法继续运行的严重错误)
  • 为公共API定义明确的错误类型(如`ErrInvalidInput`)
  • 错误信息应包含足够上下文(如参数值、操作类型)
  • 避免在循环中使用`defer`(可能导致资源未及时释放)
示例:公共API错误定义
"}}}