How to Check nil Interface in Golang?

Never check an interface for nil.

Try the following code:

type user interface{}
type staff struct{}

func compareNil() {
    var generic user

	generic = (*staff)(nil)

	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)

	generic = (nil)

	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)
}

go playground: https://play.golang.org/p/7J9DeIjgNia

Output
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 Value

goroutine 1 [running]:
reflect.Value.IsNil(...)
        /Users/xxx/.goenv/versions/1.14.0/src/reflect/value.go:1063
main.compareNil()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:48 +0x3b1
main.main()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:29 +0x142
exit status 2

Conclusion

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

References

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: