How to Check nil Interface in Golang?

Simplify Complexity
2 min readMay 15, 2022

It’s not a good idea to check an interface for nil.

Try the following code:

type user interface{}
type staff struct{}
func compareNil() {
var generic user
generic = nil
// works as expected
fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)
generic = (*staff)(nil) // fails my expectation
fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)

go playground:


value=<nil> type=*main.staff (generic==nil)=false
value=<nil> type=<nil> (generic==nil)=true

Why interface check for nil is special

An interface is a tuple of [Value, Type]. The nil interface is a tuple [nil, nil]. However, the above code is an interface containing [nil, *main.staff] which is not nil.

We can check for nil as follows:

func isNil(i interface{}) bool {                        
return i == nil || reflect.ValueOf(i).IsNil()

Here i==nil means i has [nil, nil] or has a nil value in [nil, *main.staff].

But if the interface points to a type that has no Nil value:

s := "hello"
generic = s
fmt.Printf("value=%v type=%T type=%v\n", generic, generic, reflect.ValueOf(generic).IsNil())

The code panics:

panic: reflect: call of reflect.Value.IsNil on string Valuegoroutine 1 [running]:
/Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:48 +0x3b1
/Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:29 +0x142
exit status 2


The safest way to compare nil interfaces is switch on various types, the interface can assume. Never check as myinterface == nil.


Simplify Complexity

Golang, Distributed Systems, File Systems, Python, C/C++, Linux