Go的错误处理设计

简介: Go的错误处理设计

Go 的异常错误处理只有Error,任何错误都可以直接返回,而不是使用try catch进行,如果函数在运行中出现异常我们应该把异常返回,如果没有则返回nil,且每次调用可能出现异常的函数时应主动进行检查做出反应。

// 定义异常
func fn(a int64) (b int64, err error)  {
     if a == 1 {
      return 1, errors.New("this code Seems to have encountered some problems")
     }
     return 0, nil
}
// 处理异常
func handle() {
     b, err := fn(1)
     if err != nil {
      fmt.Println(err.Error())
     } else {
      fmt.Println(b)
     }
}
复制代码

在Go中出现异常不处理也不会影响代码流程的。


我们也可以在Go中自定义错误类型,异常是一个接口,error是接口类型,我们通过自定义一个结构体进而实现error接口来增加我们的错误信息

// 自定义的异常类 实现error接口
type MyError struct {
    code    int32 
    message string
}
// 实现error接口的Error方法
func (e *MyError) Error() string {
    // 自定义异常信息
  return fmt.Errorf("this program encure err, code=%d, message=%s", e.code, e.message).Error()
}
// 抛出异常
func TryErr(a int64) (int64, error) {
    if a == 1 {
      return 1, &MyError{-1, "fail"} // 抛出自定义的异常类
    }
    return 0, nil
}
func fn() {
    i, e := TryErr(1)
    fmt.Println(i, e.Error())
}

我们需要对error 接口进行不同错误的实现进而判断做针对性处理,在日常开发中我们也经常使用

type CommonErr struct {
     code int32
     message string
}
func (e *CommonErr) Error() string {
   return fmt.Errorf("this program encure err, code=%d, message=%s", e.code, e.message).Error()
}
type CommonErr1 struct {
     code int32
     message string
}
func (e *CommonErr1) Error() string {
   return fmt.Errorf("this program encure err, code=%d, message=%s", e.code, e.message).Error()
}
// 判断错误进行处理
func dealErrByType(err error) {
     switch err.(type) {
     case *CommonErr:
      fmt.Println(err.Error())
     case *CommonErr1:
      fmt.Println(err.Error())
     }
}

我们在开发中需要注意以下几个对于错误的处理

  1. 在返回值有多个的情况且有error,error应该在最后一个
  2. 错误值进行统一,而非随便定义

在Go的错误处理中,我们没有做任何处理程序依旧会走下去,很显然这样不太好,因此Go提供了一个panic函数用于终止代码执行。

func panic(interface{})

panic函数的参数是空接口类型可以接受任何类型的对象,一旦使用了panic函数就会让Go进程终止。

func test(a int64) (b int64)  {
     panic(" test panic")
     return 1
}
func fn() {
     test(1)
     time.Sleep(3 * time.Second)
     fmt.Print(1)
}

上面的代码中我们能看到执行test函数时出现错误,后面的代码不在执行,为了防止这种情况,Go又提供了recover函数来捕获panic函数的异常

func recover() interface{}

recover函数用来获取panic函数的信息不过只能在延时调用defer语句调用函数中才可以使用


defer函数的作用就是延迟调用,等到函数返回的时候在调用,一个函数中可以包含多个,执行顺序是后入为主的顺序执行

func test(a,b,c int64) {
     defer func() {
          if a == 3 {
             fmt.Println(3)
          }
     }()
     defer func() {
          if b == 2 {
            fmt.Println(2)
          }
     }()
     defer func() {
          if c == 1 {
            fmt.Println(1)
          }
     }()
}
func fn() {
  test(3,2,1)
}

我们通过defer结合recover函数进行使用一下

func fn() {
    defer func() {
        if err := recover(); err != nil {
          fmt.Println("Panic info is: ", err)
        }
        time.Sleep(3 * time.Second)
        fmt.Println("program done")
    }()
  panic("testPanic123")
    fmt.Println("after panic")
}

defer总是会在fn函数结束之后才执行,那么 recover函数就能收集到panic发出来的异常信息并进行处理。


panic和recover函数在别的语言中就是try catch操作,但是他的作用比try catch大的多。


Go由于并没有检查时异常只有运行时异常,所以在写代码的时候我们就要尽可能的将你认为会出错的地方抛出来。


本文正在参加技术专题18期-聊聊Go语言框架

相关文章
|
7月前
|
SQL 安全 数据库连接
《Go 简易速速上手小册》第6章:错误处理和测试(2024 最新版)(上)
《Go 简易速速上手小册》第6章:错误处理和测试(2024 最新版)
72 1
|
7月前
|
Go 开发者
Go语言中的错误处理与异常机制:实践与最佳策略
【2月更文挑战第7天】Go语言以其独特的错误处理机制而闻名,它鼓励显式错误检查而不是依赖于异常。本文将探讨错误处理与异常机制在Go语言中的实际应用,并分享一些最佳实践,帮助开发者编写更加健壮和易于维护的Go代码。
|
7月前
|
存储 Cloud Native 编译器
云原生系列Go语言篇-错误处理
从其它语言转Go最大的挑战之一就是错误处理。对那些习惯了使用异常的开发者,Go采取的方法有些离经叛道。但Go语言使用的方法蕴含着牢不可破的软件工程原理。本章中,我们学习如何在Go中处理错误。我们会学习Go系统中会停止执行的错误处理panic和recover。
73 0
|
前端开发 数据库连接 Go
Go 语言错误处理为什么更推荐使用 pkg/errors 三方库?
Go 语言错误处理为什么更推荐使用 pkg/errors 三方库?
121 0
|
7月前
|
JSON 测试技术 Go
《Go 简易速速上手小册》第6章:错误处理和测试(2024 最新版)(下)
《Go 简易速速上手小册》第6章:错误处理和测试(2024 最新版)
63 0
|
3月前
|
Go
Go to Learn Go之错误处理
Go to Learn Go之错误处理
47 7
|
4月前
|
Go 开发者
理解Go语言中的错误处理
【8月更文挑战第31天】
17 0
|
4月前
|
Java Go PHP
Go从入门到放弃之错误处理
Go从入门到放弃之错误处理
|
6月前
|
Go
go错误处理
go错误处理
|
6月前
|
Go
掌握Go语言:Go语言错误处理,从基础到高级,让你的代码更健壮!(33)
掌握Go语言:Go语言错误处理,从基础到高级,让你的代码更健壮!(33)