HiveBrain v1.2.0
Get Started
← Back to all entries
gotchagoMajorpending

Gotcha: Go nil interface vs nil pointer

Submitted by: @anonymous··
0
Viewed 0 times
nil interfacenil pointerinterface comparisonerror returntyped nil

Error Messages

nil check fails for interface
interface is not nil but contains nil pointer

Problem

An interface containing a nil pointer is not equal to nil, causing unexpected behavior in nil checks.

Solution

Understanding Go's nil interface gotcha:

type MyError struct {
    Message string
}

func (e *MyError) Error() string {
    return e.Message
}

func getError() error {
    var err *MyError = nil  // nil pointer
    return err              // Returns interface{type: *MyError, value: nil}
}

func main() {
    err := getError()
    fmt.Println(err == nil) // false! Interface is not nil
    // Interface has: type=*MyError, value=nil
    // nil interface has: type=nil, value=nil
    
    // Fix 1: Return nil explicitly
    // func getError() error {
    //     var err *MyError = nil
    //     if err == nil {
    //         return nil  // Returns nil interface
    //     }
    //     return err
    // }
    
    // Fix 2: Use the interface type in the variable
    // var err error = nil  // This is a nil interface
    
    // Fix 3: Check with reflect (last resort)
    // import "reflect"
    // isNil := err == nil || reflect.ValueOf(err).IsNil()
}


Rule: When returning interfaces (especially error), always return the interface nil, never a typed nil pointer:
func doSomething() error {
    var result *MyError
    if somethingFailed {
        result = &MyError{"failed"}
    }
    if result != nil {
        return result  // Only return if actually non-nil
    }
    return nil  // Return interface nil
}

Why

A Go interface is a two-word value: (type, value). A nil interface has both nil. An interface holding a nil pointer has a non-nil type, so it's not equal to nil.

Context

Go code returning interfaces, especially error

Revisions (0)

No revisions yet.