首页 > 编程笔记 > Go语言笔记 阅读:2

Go语言Error嵌套的用法(附带实例)

Error 嵌套就是在定义的一个 error 中嵌套另一个 error。因为 error 可以嵌套,所以每次嵌套时都可以提供新的错误信息,并且保留原来的 error。

Go 语言扩展了 fmt 包的 Errorf() 函数,为该函数增加“%w”占位符生成 Error 嵌套。生成 Error 嵌套的示例代码如下:
package main

import (
    "errors"
    "fmt"
)

func main() {
    err := errors.New("结果集中没有行")
    err2 := fmt.Errorf("找不到数据,%w", err)
    fmt.Println(err2)
}
运行结果如下:

找不到数据,结果集中没有行

Unwrap()函数

既然 error 可以嵌套生成一个新的 error,那它也可以被分解,通过 errors 包中的 Unwrap() 函数可以得到被嵌套的 error。

例如,修改上面的示例,对变量 err2 使用 Unwrap() 函数,获取代码中被嵌套的原始错误信息,代码如下:
package main

import (
    "errors"
    "fmt"
)

func main() {
    err := errors.New("结果集中没有行")
    err2 := fmt.Errorf("找不到数据,%w", err)
    fmt.Println(err2)
}
运行结果如下:

结果集中没有行

Is()函数

通过 errors 包中的 Is() 函数可以判断两个 error 是否是同一个 error。Is() 函数的语法格式如下:
func Is(err, target error) bool
该函数有两个参数 err 和 target,在调用函数时,如果 err 和 target 是同一个 error 则返回 true。如果 err 是一个嵌套 error,而 target 也包含在这个嵌套 error 链中,那么也返回 true。其他情况返回 false。

修改上面的示例,使用 Is() 函数判断 err2 和 err 是否是同一个 error,代码如下:
package main

import (
    "errors"
    "fmt"
)

func main() {
    err := errors.New("结果集中没有行")
    err2 := fmt.Errorf("找不到数据,%w", err)
    fmt.Println(errors.Is(err2, err))
}
运行结果如下:

true

As()函数

通过 errors 包中的 As() 函数可以匹配指定的错误。As() 函数的语法格式如下:
func As(err error, target any) bool
该函数有两个参数 err 和 target,通过调用函数可以找到 err 链中与 target 匹配的第一个错误,如果找到,则将 target 设置为该错误值并返回 true。否则返回 false。

代码如下:
package main

import (
    "errors"
    "fmt"
)

type TestError struct {
    err string
}

func (t TestError) Error() string {
    return t.err
}

func main() {
    err := TestError{"num 不是数值类型"}
    err1 := fmt.Errorf("数据类型错误: %w", err)
    var test TestError
    if errors.As(err1, &test) {
        fmt.Println("错误信息:", test.err)
    }
}
运行结果如下:

错误信息: num不是数值类型

相关文章