Home  >  Article  >  Backend Development  >  Error while comparing in Golang

Error while comparing in Golang

王林
王林forward
2024-02-12 08:20:071031browse

在 Golang 中比较时出现错误

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!

Question content

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?

Solution

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete