Go 语言入门很简单:Go 语言的错误处理(下)

简介: 本文将介绍 Go 中的错误处理,以及为什么我们需要错误处理。

错误处理和 Is 函数

Go 语言中的 errors 包中的 Is 函数会判断目标是否有相应的错误匹配的上,在我们上一节的例子中,从 getRecords 函数中返回 nowRows 错误,然后这个错误的字符串信息从 webService 函数中返回,如果使用上 Is 函数,判断有没有查询到数据,然后才返回 noRows 错误:

package main
import (
  "errors"
  "fmt"
)
var noRows = errors.New("no rows found")
func getRecords() error {
  return noRows
}
func webService() error {
  if err := getRecords(); err != nil {
    return fmt.Errorf("Error %s when calling DB", err)
  }
  return nil
}
func main() {
  if err := webService(); err != nil {
    if errors.Is(err, noRows) {
      fmt.Printf("The searched record cannot be found. Error returned from DB is %s\n", err)
      return
    }
    fmt.Println("unknown error when searching for records")
    return
  }
  fmt.Println("webService call successful")
}


在上面的 main 函数中,我们利用 Is 函数检查这个错误是否包含 noRows 错误。


因为 if errors.Is(err, noRows) 并不满足,所以这个 if 块里并不会执行。为了使得这个错误生效,我们需要 webService  函数返回 noRows 错误时对其进行封装。


一种方法是在返回错误时使用 %w 格式指定符,而不是 %s 。因此,可以把返回错误的那一行代码修改为:

 return fmt.Errorf("Error %w when calling DB", err)


这意味着新返回的错误包裹了原来的 noRows,并且上述主函数 if 条件将成功生效,下面是修改的程序:

package main
import (
  "errors"
  "fmt"
)
var errNoRows = errors.New("no rows found")
func getRecords() error {
  return errNoRows
}
func webService() error {
  if err := getRecords(); err != nil {
    return fmt.Errorf("error %w when calling DB", err)
  }
  return nil
}
func main() {
  if err := webService(); err != nil {
    if errors.Is(err, errNoRows) {
      fmt.Printf("The searched record cannot be found. Error returned from DB is %s\n", err)
      return
    }
    fmt.Println("unknown error when searching for records")
    return
  }
  fmt.Println("webService call successful")
}


运行结果:

$ go run .
The searched record cannot be found. Error returned from DB is error no rows found when calling DB

As 函数

errors 包中的 As 函数尝试把输入的错误转换为目标错误类型。如果错误链中的任何一个错误与目标错误匹配,就返回 true。

package main
import (
  "errors"
  "fmt"
)
type DBError struct {
  desc string
}
func (dbError DBError) Error() string {
  return dbError.desc
}
func getRecords() error {
  return DBError{
    desc: "no rows found",
  }
}
func webService() error {
  if err := getRecords(); err != nil {
    return fmt.Errorf("Error %w when calling DB", err)
  }
  return nil
}
func main() {
  if err := webService(); err != nil {
    var dbError DBError
    if errors.As(err, &dbError) {
      fmt.Printf("The searched record cannot be found. Error returned from DB is %s", dbError)
      return
    }
    fmt.Println("unknown error when searching records")
    return
  }
  fmt.Println("webservice call successful")
}


在上面的程序中,我们修改了 getRecord 函数,返回一个 DBError 类型的自定义错误。


main 函数中,我们试图将 webService() 函数调用返回的错误转换为 DBError 类型。if errors.As(err, &dbError) 语句将会成功,因为我们已经把错误包起来了。运行这个代码,将会返回:

The searched record cannot be found. Error returned from DB is no rows found  

总结

程序可能会随时都会出现异常,需要我们在开发过程中提前做好异常处理。所以本文介绍了 Go 语言中的错误处理,Go 标准库提供的两种创建 error 的方式,并介绍了如何检查错误和如果传递错误。


相关文章
|
1天前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
28天前
|
Go
Go to Learn Go之错误处理
Go to Learn Go之错误处理
37 7
|
3天前
|
存储 安全 Go
Go语言切片:从入门到精通的深度探索###
本文深入浅出地剖析了Go语言中切片(Slice)这一核心概念,从其定义、内部结构、基本操作到高级特性与最佳实践,为读者提供了一个全面而深入的理解。通过对比数组,揭示切片的灵活性与高效性,并探讨其在并发编程中的应用优势。本文旨在帮助开发者更好地掌握切片,提升Go语言编程技能。 ###
|
2月前
|
Go 开发者
理解Go语言中的错误处理
【8月更文挑战第31天】
10 0
|
2月前
|
Unix Go
Go从入门到放弃之时间操作
Go从入门到放弃之时间操作
|
5月前
|
Go 开发者
Go语言中的错误处理与异常机制:实践与最佳策略
【2月更文挑战第7天】Go语言以其独特的错误处理机制而闻名,它鼓励显式错误检查而不是依赖于异常。本文将探讨错误处理与异常机制在Go语言中的实际应用,并分享一些最佳实践,帮助开发者编写更加健壮和易于维护的Go代码。
|
5月前
|
存储 Cloud Native 编译器
云原生系列Go语言篇-错误处理
从其它语言转Go最大的挑战之一就是错误处理。对那些习惯了使用异常的开发者,Go采取的方法有些离经叛道。但Go语言使用的方法蕴含着牢不可破的软件工程原理。本章中,我们学习如何在Go中处理错误。我们会学习Go系统中会停止执行的错误处理panic和recover。
69 0
|
前端开发 数据库连接 Go
Go 语言错误处理为什么更推荐使用 pkg/errors 三方库?
Go 语言错误处理为什么更推荐使用 pkg/errors 三方库?
101 0
|
Go 开发者
错误处理不再难!Go语言错误处理完全指南
错误处理不再难!Go语言错误处理完全指南
179 0
|
4月前
|
Go
掌握Go语言:Go语言错误处理,从基础到高级,让你的代码更健壮!(33)
掌握Go语言:Go语言错误处理,从基础到高级,让你的代码更健壮!(33)