Home  >  Article  >  Backend Development  >  Why does a nil instance of a struct that satisfies the error interface not compare equal to nil?

Why does a nil instance of a struct that satisfies the error interface not compare equal to nil?

Susan Sarandon
Susan SarandonOriginal
2024-10-31 07:50:30839browse

Why does a nil instance of a struct that satisfies the error interface not compare equal to nil?

Nil Nil Interface Comparison Puzzle

Despite satisfying the error interface, a struct with a nil instance does not behave as expected when compared to nil.

Question:

Why does the following code not output "Error is nil"?

<code class="go">type Goof struct {}

func (goof *Goof) Error() string {
    return fmt.Sprintf("I'm a goof")
}

func TestError(err error) {
    if err == nil {
        fmt.Println("Error is nil")
    } else {
        fmt.Println("Error is not nil")
    }
}

func main() {
    var g *Goof // nil
    TestError(g) // expect "Error is not nil"
}</code>

Answer:

In Go, interface comparisons consider both type and value. While the Goof type implements the error interface, a nil instance of Goof (*Goof)(nil) has a distinct type from error(nil).

Solution:

To address this, you can adopt one of the following approaches:

  • Declare err error instead of var g *Goof. This initializes err to the zero value of the error type, which is nil.
  • In functions returning errors, return nil explicitly instead of leaving it implicit.

For more details, refer to the extended response below:

Extended Response:

Interface values consist of two components: a type and a dynamic value. A nil interface value contains both a nil type and a nil value. In our case, (*Goof)(nil) has a non-nil type (Goof), but a nil value.

Additionally, Go's equality operator (==) strictly checks for type identity. Hence, comparing (*Goof)(nil) to error(nil) fails because they are of different types.

This behavior is consistent with other type-checking in Go. For instance, in the following code, the underlying data is the same (3), but the variables have different types, resulting in inequality when stored in interfaces:

<code class="go">var x int = 3
var y Bob = 3
var ix, iy interface{} = x, y
fmt.Println(ix == iy) // false</code>

The above is the detailed content of Why does a nil instance of a struct that satisfies the error interface not compare equal to nil?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn