介绍

  1. 在C语言中通过返回 -1 或者 NULL 之类的信息来表示错误,但是对于使用者来说,如果不查看相应的 API 说明文档,根本搞不清楚这个返回值究竟代表什么意思,比如返回 0 是成功还是失败?
  2. Go语言中引入 error 接口类型作为错误处理的标准模式,如果函数要返回错误,则返回值类型列表中肯定包含 error。error 处理过程类似于C语言中的错误码,可逐层返回,直到被处理。与其他语言的异常相比,Go语言的方法相对更加容易、直观。
  3. 一般情况下,如果函数需要返回错误,就将 error 作为多个返回值中的最后一个(但这并非是强制要求)。

定义

error 是 Go 系统声明的接口类型,所有符合 Error() string 格式的方法,都能实现错误接口,Error() 方法返回错误的具体描述,使用者可以通过这个字符串知道发生了什么错误。

  1. type error interface {
  2. Error() string
  3. }

使用

  1. func Sqrt(f float64) (float64, error) {
  2. if f < 0 {
  3. return -1, errors.New("math: square root of negative number")
  4. }
  5. return math.Sqrt(f), nil
  6. }
  7. func main() {
  8. result, err := Sqrt(-13)
  9. if err != nil {
  10. fmt.Println(err)
  11. } else {
  12. fmt.Println(result)
  13. }
  14. }

自定义

1.定义错误

在Go语言中,使用 errors 包进行错误的定义,格式如下:

  1. var err = errors.New("this is an error")

2.自定义错误

错误对象都要实现 error 接口的 Error() 方法,这样,所有的错误都可以获得字符串的描述,如果想进一步知道错误的详细信息,可以通过类型断言,将错误对象转为具体的错误类型进行错误详细信息的获取。

  1. // 声明一个解析错误
  2. type ParseError struct {
  3. Filename string // 文件名
  4. Line int // 行号
  5. }
  6. // 实现error接口,返回错误描述
  7. func (e *ParseError) Error() string {
  8. return fmt.Sprintf("%s:%d", e.Filename, e.Line)
  9. }
  10. // 创建一些解析错误
  11. func newParseError(filename string, line int) error {
  12. return &ParseError{filename, line}
  13. }
  14. func main() {
  15. var e error
  16. // 创建一个错误实例,包含文件名和行号
  17. e = newParseError("main.go", 1)
  18. // 通过error接口查看错误描述
  19. fmt.Println(e.Error())
  20. // 根据错误接口具体的类型,获取详细错误信息
  21. switch detail := e.(type) {
  22. case *ParseError: // 这是一个解析错误
  23. fmt.Printf("Filename: %s Line: %d\n", detail.Filename, detail.Line)
  24. default: // 其他类型的错误
  25. fmt.Println("other error")
  26. }
  27. }