Golang / GoLang Interfaces and Object Oriented Interview Questions
Explain the nil interface trap in Go. Why does a typed nil fail the '!= nil' check?
This is one of the most frequently asked Go interview questions. The trap: an interface value is only nil when both its type pointer and its data pointer are zero. If you assign a nil pointer of a concrete type to an interface variable, the type pointer becomes non-zero — so the interface is not nil, even though the data it holds is nil.
type MyError struct{ code int } func (e *MyError) Error() string { return fmt.Sprintf("error %d", e.code) } // BUGGY function â looks like it returns nil on the happy path func riskyOperation(fail bool) error { var err *MyError // nil *MyError if fail { err = &MyError{code: 42} } return err // WRONG: assigns typed nil to error interface // interface layout: {type=*MyError, data=nil} } e := riskyOperation(false) if e != nil { // TRUE â interface is non-nil even though data is nil! fmt.Println("BUG: this branch runs unexpectedly:", e) } // Correct fix: return untyped nil func safeOperation(fail bool) error { if fail { return &MyError{code: 42} } return nil // untyped nil â both words zeroed â truly nil interface } // Another correct approach: keep return type concrete func concreteReturn(fail bool) *MyError { if fail { return &MyError{code: 42} } return nil // nil pointer returned as concrete type, not interface } // Debug a suspicious interface with reflect e2 := riskyOperation(false) fmt.Println(e2 == nil) // false fmt.Println(reflect.ValueOf(e2).IsNil()) // true â data IS nil fmt.Printf("%T\n", e2) // *main.MyError
Root cause: the language spec defines interface equality as requiring both words to be zero. Assigning any concrete type (even a nil pointer of that type) populates the type word. The only way to produce a nil interface is to assign the bare nil literal or another nil interface variable.
Rule: when your function returns an interface type (like error), always return the bare nil keyword on the success path. Never return a typed nil pointer (var e *MyError; return e).
More Related questions...