When performing comparison operations in Golang, you sometimes encounter some errors. These errors may cause the program to behave improperly or produce unexpected results. This article will use the introduction of PHP editor strawberry to analyze the errors that may occur when comparing in Golang and provide corresponding solutions. By understanding these common errors, we can better understand and use Golang's comparison operations and improve the stability and correctness of the program. Let’s explore together!
I ran into a problem today while trying to implement a custom error. My service has two types of errors: regular errors for internal errors and user errors for handling user-related errors. So I have a structure for user errors that contains some metadata and functions to handle the errors. In this function I use a wrapper for standard error. As function. But the way it works is weird: for some reason, it also treats common errors as user errors. Here is the code snippet:
<code>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)) } </code>
Here I'm testing a function that accepts two errors and compares them (As and AsV2). The only difference is that the second function accepts the target error's interface instead of the error type. In the function IsUserError I manually create the UserError pointer and provide it to the Errors.As function. But when outputting this program I get this:
true true false
So my question is why the error occurs in the first two cases. That is, it's the same type of error, but only in the third case does it give the correct answer? Am I misunderstanding how interfaces work in Go?
This is not the case. In the first two cases, it correctly reports errors as Error
and interface{}
respectively. The unnecessary wrapper function you added is creating an indirection which makes it even more confusing, but if you call:
var emptyError *UserError fmt.Println(errors.As(userError, emptyError))
You get the expected result. IsUserError
works as expected because it passes the correct type to errors.Is
. I've cleaned up your code to work properly (Error
takes a non-pointer receiver and doesn't leave emptyError
as nil
), you can check it here See it in action: 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)) }
The above is the detailed content of Error while comparing in Golang. For more information, please follow other related articles on the PHP Chinese website!