Equal比较方法
错误对象支持比较,Equal方法用于完整判断两个error是否相同。主要通过以下方法:
// Equal reports whether current error `err` equals to error `target`.
// Please note that, in default comparison for `Error`,
// the errors are considered the same if both the `code` and `text` of them are the same.
func Equal(err, target error) bool接口定义
如果自定义的错误数据结构需要支持比较,需要自定义的错误结构实现以下接口:
// IEqual is the interface for Equal feature.
type IEqual interface {
Error() string
Equal(target error) bool
}通过GoFrame框架错误组件创建的错误对象已经实现了该接口,组件默认比较逻辑判断错误码和错误信息。
:::info
需要注意,如果两个错误均不带错误码,并且错误信息相等,那么组件认为两个错误相等。
:::
使用示例
func ExampleEqual() {
err1 := errors.New("permission denied")
err2 := gerror.New("permission denied")
err3 := gerror.NewCode(gcode.CodeNotAuthorized, "permission denied")
fmt.Println(gerror.Equal(err1, err2))
fmt.Println(gerror.Equal(err2, err3))
// Output:
// true
// false
}Is判断错误链中是否包含目标错误
说明:
Is方法用于判断错误链中是否包含特定的目标错误。该方法是对Go标准库errors.Is的封装,保证了与标准库相同的性能。格式:
Is(err, target error) bool示例:
func ExampleIs() { // 创建一个特定的错误作为目标 targetErr := gerror.New("target error") // 包装错误 err1 := gerror.Wrap(targetErr, "wrap error 1") err2 := gerror.Wrap(err1, "wrap error 2") // 使用Is判断是否包含目标错误 fmt.Println(gerror.Is(err2, targetErr)) // 与不相关的错误进行判断 otherErr := gerror.New("other error") fmt.Println(gerror.Is(err2, otherErr)) // Output: // true // false }
As将错误转换为特定类型
说明:
As方法用于将错误链中的错误转换为特定类型。它会在错误链中查找第一个与目标类型匹配的错误,如果找到,则将其转换为目标类型并返回true。该方法是对Go标准库errors.As的封装,保证了与标准库相同的性能。格式:
As(err error, target any) bool示例:
// 自定义错误类型 type MyError struct { Message string Code int } // 实现error接口 func (e *MyError) Error() string { return fmt.Sprintf("code: %d, message: %s", e.Code, e.Message) } func ExampleAs() { // 创建一个自定义错误 originalErr := &MyError{Message: "database connection failed", Code: 500} // 包装错误 err := gerror.Wrap(originalErr, "operation failed") // 尝试将错误转换为MyError类型 var myErr *MyError if gerror.As(err, &myErr) { fmt.Println("Error code:", myErr.Code) fmt.Println("Error message:", myErr.Message) } // 尝试转换为不匹配的类型 type OtherError struct{} var otherErr *OtherError fmt.Println(gerror.As(err, &otherErr)) // Output: // Error code: 500 // Error message: database connection failed // false }
As 方法在以下场景中特别有用:
类型断言:当您需要从错误链中提取特定类型的错误信息时。
错误处理:根据错误类型执行不同的处理逻辑。
自定义错误恢复:当需要从错误中提取特定信息来实现错误恢复机制时。
下面是一个实际应用的例子:
package main
import (
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
)
// 数据库错误
type DBError struct {
Table string
Message string
}
func (e *DBError) Error() string {
return fmt.Sprintf("database error on table '%s': %s", e.Table, e.Message)
}
// 认证错误
type AuthError struct {
Username string
Message string
}
func (e *AuthError) Error() string {
return fmt.Sprintf("authentication error for user '%s': %s", e.Username, e.Message)
}
// 模拟数据库操作
func queryDatabase() error {
return gerror.Wrap(&DBError{
Table: "users",
Message: "connection timeout",
}, "database query failed")
}
// 模拟用户认证
func authenticateUser() error {
return gerror.Wrap(&AuthError{
Username: "john_doe",
Message: "invalid password",
}, "authentication failed")
}
// 处理不同类型的错误
func handleError(err error) {
// 尝试将错误转换为数据库错误
var dbErr *DBError
if gerror.As(err, &dbErr) {
fmt.Println("Database error detected:")
fmt.Println(" Table:", dbErr.Table)
fmt.Println(" Message:", dbErr.Message)
fmt.Println(" Recommended action: Check database connection and retry")
return
}
// 尝试将错误转换为认证错误
var authErr *AuthError
if gerror.As(err, &authErr) {
fmt.Println("Authentication error detected:")
fmt.Println(" Username:", authErr.Username)
fmt.Println(" Message:", authErr.Message)
fmt.Println(" Recommended action: Verify credentials and try again")
return
}
// 其他错误类型
fmt.Println("Unknown error:", err.Error())
}
func main() {
// 模拟数据库错误
err1 := queryDatabase()
handleError(err1)
fmt.Println()
// 模拟认证错误
err2 := authenticateUser()
handleError(err2)
}运行结果:
Database error detected:
Table: users
Message: connection timeout
Recommended action: Check database connection and retry
Authentication error detected:
Username: john_doe
Message: invalid password
Recommended action: Verify credentials and try again