Ron Liu Blog

The confusion nil pointer in golang

February 26, 2023

When I firstly learn golang, I think nil is just like undefined in javascript. It just means it point to nothing. If you think the same way, let’s check the following puzzles.

Can I assign a untyped nil directly to a variable?

  nilPointer := nil  // <-golang compile error: use of untyped nil in assignment

So the answer is NO, you cannot.

Does typed nil equals to untyped nil?

  var dogPointer *Dog = nil
  fmt.Println("Does (*Dog)nil equal to untyped nil?", dogPointer == nil)  // Does (*Dog)nil equal to untyped nil? true

Yes, as you expect

But dees interface{} nil pointing to typed nil equal to untyped nil?

	var dogPointer *Dog = nil
	pointer = dogPointer
	fmt.Println("Dees untyped nil pointing to  equal to (*Dog)nil ?", pointer == nil) // Does (*Dog)nil equal to untyped nil? true

Oh, no, that’s wired. Why???

OK, Does interface{} nil equal to untyped nil ?

var pointer interface{} = nil
fmt.Println("Does interface{} nil equal to untyped nil ?", pointer == nil) // Does interface{} nil equal to untyped nil ? true

The answer is Yes, I think it makes sense

And that’s why we can use err == nil ?

func call() error {
    return nil
}
if call() == nil {
    // ...
}

error is a interface, and that’s why we can compare with a untyped nil.

How about other interface assigned as nil equals to untyped nil?

type Animal interface{}
var animal Animal = nil
fmt.Println("Does a normal interface nil equal to untyped nil?", animal == nil)  // Does a normal interface nil equal to untyped nil? true

Oh, interface null is actually untyped nil, emm, makes sense.

Can a typed nil call member function?

type Dog struct{}
func (dog *Dog) Bark() {
	fmt.Println("Dog is barking")
}
var dogPointer Dog = nil
dogPointer.Bark()  // Dog is barking

The answer is YES, yeah! What will happen if I want to cast a interface {} nil to a type?

    var pointer interface{} = nil
	aPointer, ok := pointer.(*Dog)
	fmt.Println("Hello", aPointer, ok) // Hello <nil> false

Yeah, it will fail, makes sense What will happen if I want to cast a typed nil to the type?

	pointer = dogPointer
	aPointer, ok = pointer.(*Dog)
	fmt.Println("Hello", aPointer, ok) // Hello <nil> true

Are you confused ? I am not sure, but I am haha!