0

Can someone provide some explanation about this code behaviour: https://play.golang.org/p/_TjQhthHl3

package main

import (
    "fmt"
)

type MyError struct{}
func (e *MyError) Error() string {
    return "some error"
}

func main() {
    var err error
    if err == nil {
        fmt.Println("[OK] err is nil ...")
    }else{
        fmt.Println("[KO] err is NOT nil...")
    }
    isNil(err)


    var err2 *MyError
    if err2 == nil {
        fmt.Println("[OK] err2 is nil ...")
    }else{
        fmt.Println("[KO] err2 is NOT nil...")
    }
    isNil(err2)
}

func isNil(err error){
    if err == nil {
        fmt.Println("[OK] ... still nil")
    }else{
        fmt.Println("[KO] .. why not nil?")
    }
}

Output is:

[OK] err is nil ...
[OK] ... still nil
[OK] err2 is nil ...
[KO] .. why err2 not nil?

I found this post Check for nil and nil interface in Go but I still don't get it...

zerkms
  • 249,484
  • 69
  • 436
  • 539
Martin Magakian
  • 3,746
  • 5
  • 37
  • 53

3 Answers3

2

error is a built-in interface, and *MyError implements that interface. Even though the value of err2 is nil, when you pass it to isNil, the function gets a non-nil interface value. That value contains information about the type (*MyError) and the value itself, which is a nil pointer.

If you try printing err in isNil, you'll see that in the second case, you get "some error" even though err2 is nil. This demonstrates why err is not nil in that case (it has to contain the type information).

Andy Schweig
  • 6,597
  • 2
  • 16
  • 22
1

From my understanding your var err2 *MyError definition is generating a pointer to the struct definition and NOT an actual instantiated object.

Mike Wilding
  • 49
  • 1
  • 5
  • It does not explain why it's not `nil`. It declares a pointer and initialises it with the `nil `value. – zerkms Jun 13 '17 at 21:33
1

In Go interface types are represented by a structure with 2 fields: one denotes its actual type and the other is a pointer to the value.

It means that an interface value is never equal to nil unless the value you passed is actually a nil value.

Relevant and good talk: GopherCon 2016: Francesc Campoy - Understanding nil

zerkms
  • 249,484
  • 69
  • 436
  • 539