在Golang中进行比较操作时,有时会遇到一些错误。这些错误可能导致程序运行不正常或产生意想不到的结果。本文将通过php小编草莓的介绍,为大家解析在Golang中比较时可能出现的错误,并提供相应的解决方案。通过了解这些常见错误,我们可以更好地理解和使用Golang的比较操作,提高程序的稳定性和正确性。让我们一起来探索吧!
问题内容
今天我在尝试实现自定义错误时遇到了问题。我的服务有两种类型的错误:内部错误的常规错误和处理用户相关错误的用户错误。所以我有用于用户错误的结构,其中包含一些元数据和处理错误的函数。在此函数中,我对标准错误使用包装器。As 函数。但它的工作方式很奇怪:出于某种原因,它也将常见错误视为用户错误。
这是代码片段:
package main
import (
"errors"
"fmt"
)
type UserError struct {
Message string
}
func (u *UserError) Error() string {
return u.Message
}
func As(sourceError, targetError error) bool {
return errors.As(sourceError, &targetError)
}
func AsV2(sourceError error, targetError interface{}) bool {
return errors.As(sourceError, &targetError)
}
func IsUserError(err error) bool {
var userError *UserError
return errors.As(err, &userError)
}
func main() {
userError := errors.New("test Error")
var emptyError *UserError
fmt.Println(As(userError, emptyError))
fmt.Println(AsV2(userError, emptyError))
fmt.Println(IsUserError(userError))
}
登录后复制
在这里,我正在测试接受两个错误并比较它们的函数(As 和 AsV2)。唯一的区别是第二个函数接受目标错误的接口而不是错误类型。在函数 IsUserError 中,我手动创建 UserError 指针并提供给Errors.As 函数。但在输出这个程序时我得到这个:
true
true
false
登录后复制
所以我的问题是为什么在前两种情况下会出现错误。也就是说,这是相同类型的错误,但只有在第三种情况下它才会给出正确的答案?我是否误解了 Go 中接口的工作原理?
解决方法
事实并非如此。在前两种情况下,它正确地报告错误分别为 Error
和 interface{}
。您添加的不必要的包装函数正在创建一个间接,这使其更加混乱,但如果您调用:
var emptyError *UserError
fmt.Println(errors.As(userError, emptyError))
登录后复制
您得到了预期的结果。 IsUserError
按预期工作,因为它将正确的类型传递给 errors.Is
。我已经清理了您的代码以正常工作(Error
采用非指针接收器,并且不将 emptyError
保留为 nil
),您可以在此处查看它的运行情况: https://go.dev/play/p/c5EPB5IGeD5
type UserError struct {
Message string
}
func (u UserError) Error() string {
return u.Message
}
func main() {
userError := errors.New("test Error")
var emptyError UserError
fmt.Println(errors.As(userError, &emptyError))
}
登录后复制
以上就是在 Golang 中比较时出现错误的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!