第六章:错误处置惩罚 2.错误处置惩罚 --Go 语言轻松入门 ...

打印 上一主题 下一主题

主题 842|帖子 842|积分 2526

在 Go 语言中,错误处置惩罚是一个非常重要的主题。Go 接纳了一种简单但强大的方式来处置惩罚错误:函数通常返回一个 error 类型的值,调用者可以检查这个值是否为 nil 来判断是否有错误发生。假如发生了错误,可以通过 error 接口获取错误信息。
下面是一些常见的错误处置惩罚模式和最佳实践:
1. 基本错误处置惩罚

最基本的错误处置惩罚模式是检查函数返回的 error 是否为 nil。假如不为 nil,则表示有错误发生。
  1. package main
  2. import (
  3.         "errors"
  4.         "fmt"
  5. )
  6. // divide 函数用于执行两个整数的除法操作。
  7. // 它接受两个整数参数 a 和 b,返回两者的商和一个错误。
  8. // 如果除数 b 为零,函数将返回一个错误,说明除零操作是不允许的。
  9. func divide(a, b int) (int, error) {
  10.         if b == 0 {
  11.                 return 0, errors.New("division by zero")
  12.         }
  13.         return a / b, nil
  14. }
  15. func main() {
  16.         // 调用 divide 函数进行除法操作。
  17.         // 这里传入的参数是 10 和 0,意在测试函数如何处理除零的情况。
  18.         result, err := divide(10, 0)
  19.         if err != nil {
  20.                 // 如果 divide 函数返回了一个错误,这里将输出错误信息。
  21.                 fmt.Println("Error:", err)
  22.         } else {
  23.                 // 如果 divide 函数没有返回错误,这里将输出计算结果。
  24.                 fmt.Printf("Result: %d\n", result)
  25.         }
  26. }
复制代码

2. 使用 fmt.Errorf 创建格式化错误

fmt.Errorf 可以用来创建带有格式化字符串的错误。
  1. package main
  2. import (
  3.         "fmt"
  4. )
  5. // compute 函数计算两个整数的和。
  6. // 参数:
  7. //
  8. //        a - 第一个整数。
  9. //        b - 第二个整数。
  10. //
  11. // 返回值:
  12. //
  13. //        两个整数的和。
  14. //        如果 b 为负数,则返回错误。
  15. func compute(a, b int) (int, error) {
  16.         if b < 0 {
  17.                 return 0, fmt.Errorf("negative value for b: %d", b)
  18.         }
  19.         // 进行计算...
  20.         return a + b, nil
  21. }
  22. func main() {
  23.         result, err := compute(10, -5)
  24.         if err != nil {
  25.                 fmt.Println("Error:", err)
  26.         } else {
  27.                 fmt.Printf("Result: %d\n", result)
  28.         }
  29. }
复制代码

3. 自定义错误类型

你可以定义自己的错误类型,并实现 error 接口。
  1. package main
  2. import (
  3.         "fmt"
  4. )
  5. // MyError 是一个自定义错误类型,包含错误消息和错误代码。
  6. type MyError struct {
  7.         Message string
  8.         Code    int
  9. }
  10. // Error 实现了 error 接口,返回错误消息。
  11. func (e *MyError) Error() string {
  12.         return e.Message
  13. }
  14. // doSomething 模拟一个可能会产生错误的函数。
  15. // 返回一个指向 MyError 的指针,表示发生错误。
  16. func doSomething() error {
  17.         return &MyError{"something went wrong", 404}
  18. }
  19. func main() {
  20.         // 调用 doSomething 函数并检查是否有错误。
  21.         err := doSomething()
  22.         // 如果发生错误,打印错误消息。
  23.         if err != nil {
  24.                 fmt.Println("Error:", err)
  25.         }
  26. }
复制代码

4. 错误包装与解包

从 Go 1.13 开始,尺度库提供了 errors.Is 和 errors.As 函数来处置惩罚被包装的错误。
  1. package main
  2. import (
  3.         "errors"
  4.         "fmt"
  5. )
  6. // ErrNotFound 是一个预定义的错误,表示资源未找到。
  7. var ErrNotFound = errors.New("not found")
  8. // fetchResource 尝试获取指定ID的资源。
  9. // 如果资源不存在,返回一个带有详细信息的错误。
  10. func fetchResource(id string) error {
  11.         if id == "missing" {
  12.                 return fmt.Errorf("resource with ID %s not found: %w", id, ErrNotFound)
  13.         }
  14.         return nil
  15. }
  16. func main() {
  17.         // 调用 fetchResource 函数并检查返回的错误。
  18.         err := fetchResource("missing")
  19.         // 如果错误是 ErrNotFound,打印“资源未找到”。
  20.         if errors.Is(err, ErrNotFound) {
  21.                 fmt.Println("Resource not found")
  22.         } else if err != nil {
  23.                 // 如果是其他类型的错误,打印“发生意外错误”并显示错误详情。
  24.                 fmt.Println("An unexpected error occurred:", err)
  25.         }
  26. }
复制代码

5. 使用 defer 和 recover 处置惩罚 panic

对于运行时非常(panic),可以使用 defer 和 recover 来捕捉并处置惩罚。
  1. package main
  2. import "fmt"
  3. // safeDivide 安全地执行除法操作。
  4. // 参数:
  5. //
  6. //        a: 被除数
  7. //        b: 除数
  8. //
  9. // 返回值:
  10. //
  11. //        result: 除法结果
  12. //        err: 如果发生错误,返回错误信息
  13. func safeDivide(a, b int) (result int, err error) {
  14.         // 使用 defer 和 recover 捕获并处理 panic
  15.         defer func() {
  16.                 if r := recover(); r != nil {
  17.                         err = fmt.Errorf("panic recovered: %v", r)
  18.                 }
  19.         }()
  20.         // 如果除数为 0,触发 panic
  21.         if b == 0 {
  22.                 panic("division by zero")
  23.         }
  24.         // 正常情况下返回除法结果
  25.         return a / b, nil
  26. }
  27. func main() {
  28.         // 调用 safeDivide 函数并检查返回的错误
  29.         result, err := safeDivide(10, 0)
  30.         if err != nil {
  31.                 // 如果有错误,打印错误信息
  32.                 fmt.Println("Error:", err)
  33.         } else {
  34.                 // 如果没有错误,打印除法结果
  35.                 fmt.Printf("Result: %d\n", result)
  36.         }
  37. }
复制代码

6. 使用 log 包记载错误

在现实应用中,你可能希望将错误记载到日志文件中,而不是直接打印到控制台。
  1. package main
  2. import (
  3.         "errors"
  4.         "log"
  5.         "os"
  6. )
  7. // divide 函数用于执行两个整数的除法操作。
  8. // 它接受两个整数参数 a 和 b,返回两者的商和一个错误。
  9. // 如果除数 b 为零,函数将返回一个错误,说明除零操作是不允许的。
  10. func divide(a, b int) (int, error) {
  11.         if b == 0 {
  12.                 return 0, errors.New("division by zero")
  13.         }
  14.         return a / b, nil
  15. }
  16. func main() {
  17.         // 打开或创建日志文件,模式为追加写入,权限为 0666
  18.         logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  19.         if err != nil {
  20.                 // 如果打开日志文件失败,记录致命错误并退出程序
  21.                 log.Fatalf("Failed to open log file: %v", err)
  22.         }
  23.         // 确保在程序结束时关闭日志文件
  24.         defer logFile.Close()
  25.         // 设置日志输出到文件
  26.         log.SetOutput(logFile)
  27.         // 调用 divide 函数并检查返回的错误
  28.         result, err := divide(10, 0)
  29.         if err != nil {
  30.                 // 如果有错误,记录错误信息
  31.                 log.Println("Error:", err)
  32.         } else {
  33.                 // 如果没有错误,记录除法结果
  34.                 log.Printf("Result: %d\n", result)
  35.         }
  36. }
复制代码

这些示例展示了 Go 中几种常见的错误处置惩罚方法。通过这些方法,你可以有效地管理和处置惩罚程序中的错误,提高代码的结实性和可维护性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表