errors.Is用于判断错误链中是否存在指定错误,它通过递归遍历错误链实现深层比较,而直接比较仅判断错误实例是否相同;自定义错误可通过实现Is方法支持errors.Is;errors.As则用于判断并提取特定类型的错误;错误链过长理论上影响性能但实际可忽略;在测试中使用errors.Is可更可靠地验证错误。

Golang的
errors.Is
解决方案
errors.Is
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
func main() {
err := someFunction()
if errors.Is(err, ErrNotFound) {
fmt.Println("资源未找到")
} else if err != nil {
fmt.Println("其他错误:", err)
}
}
func someFunction() error {
// 模拟一个可能返回 ErrNotFound 的函数
return fmt.Errorf("操作失败: %w", ErrNotFound)
}在这个例子中,
errors.Is
someFunction
ErrNotFound
fmt.Errorf("%w", err)errors.Is
立即学习“go语言免费学习笔记(深入)”;
副标题1: errors.Is 与直接比较的区别是什么?
直接比较(
err == ErrNotFound
errors.Is
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
func main() {
err := fmt.Errorf("wrapper: %w", ErrNotFound)
// 直接比较
if err == ErrNotFound {
fmt.Println("直接比较:相等") // 不会执行
} else {
fmt.Println("直接比较:不相等") // 会执行
}
// 使用 errors.Is
if errors.Is(err, ErrNotFound) {
fmt.Println("errors.Is:相等") // 会执行
} else {
fmt.Println("errors.Is:不相等")
}
}可以看到,直接比较失败了,因为
err
ErrNotFound
errors.Is
ErrNotFound
副标题2: 如何自定义错误类型并使用 errors.Is 进行判断?
你可以自定义错误类型,并让
errors.Is
Is(error) bool
package main
import (
"errors"
"fmt"
)
type MyError struct {
Code int
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("Code: %d, Message: %s", e.Code, e.Message)
}
func (e *MyError) Is(target error) bool {
t, ok := target.(*MyError)
if !ok {
return false
}
return e.Code == t.Code
}
var ErrMyError = &MyError{Code: 100, Message: "My Custom Error"}
func main() {
err := fmt.Errorf("wrapped: %w", ErrMyError)
if errors.Is(err, &MyError{Code: 100, Message: ""}) {
fmt.Println("errors.Is 匹配 MyError") // 会执行
} else {
fmt.Println("errors.Is 不匹配 MyError")
}
}在这个例子中,
MyError
Is
errors.Is
MyError
Is
Code
副标题3: errors.As 函数的作用是什么?它和 errors.Is 有什么区别?
errors.As
package main
import (
"errors"
"fmt"
)
type MyError struct {
Code int
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("Code: %d, Message: %s", e.Code, e.Message)
}
func main() {
var myErr *MyError
err := fmt.Errorf("wrapped: %w", &MyError{Code: 200, Message: "Another Error"})
if errors.As(err, &myErr) {
fmt.Printf("找到 MyError, Code: %d, Message: %s\n", myErr.Code, myErr.Message) // 会执行
} else {
fmt.Println("未找到 MyError")
}
}errors.Is
errors.As
errors.Is
errors.As
errors.As
副标题4: 错误链过长会影响 errors.Is 的性能吗?
理论上,错误链越长,
errors.Is
副标题5: 如何在测试中使用 errors.Is 来验证错误?
在测试中,
errors.Is
package main
import (
"errors"
"testing"
)
var ErrTest = errors.New("test error")
func MyFunc() error {
return ErrTest
}
func TestMyFunc(t *testing.T) {
err := MyFunc()
if !errors.Is(err, ErrTest) {
t.Errorf("expected ErrTest, got %v", err)
}
}这种方式比直接比较错误更健壮,因为即使错误被包装了,测试仍然能够通过。
以上就是Golang的errors.Is函数如何检查错误链中是否存在特定错误的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号