skip to content
Alvin Lucillo

Defining method on nil pointer in Go

/ 2 min read

💻 Tech

In Go, you can define a method on a nil pointer. This is useful when you want to avoid nil pointer dereference errors or when you want to provide a default value when the receiver is nil. Because of this pointer receivers can be safely called on nil pointers. However, this poses a question: should the callee handle the nil pointer or should the caller handle it? That would be for a separate discussion. For now, here’s the code that demonstrates the subject of this post.


type Foo struct {
	ID string
}

// This is a pointer receiver
// It doesn't dereference the pointer because it operates on the original value the pointer points to, not a copy of it.
// If you try to operate on a copy of the value, you will get an error because it is nil.
// But here, it checks if the pointer is nil and ID is not accessed.
// With this, you can safely call this method on a nil pointer.
func (f *Foo) Bar() string {
	if f != nil {
		return f.ID
	}

	return "f is nil. how cool is that? 😎"
}

// This is a value receiver
// It operates on the copy of the value, so it will dereference the pointer to get the value.
// The pointer here is f. So, if you call this method on a nil pointer, you will get an error.
func (f Foo) Baz() string {
	return "this is unreachable code"
}

func main() {
	var f Foo = nil
	fmt.Println(f.Bar()) // Prints something - OK
	fmt.Println(f.Baz()) // Invalid memory address error - Fail

    // Note: You need to comment out the prevous line (call to f.Bar()) to run the following code; otherwise, it's unreachable code.

	// The code below is similar to the previous one, but this uses method expressions syntax.
	// f here is a nil pointer but the receiver is pointer receiver so it's safe to call the method.
	fmt.Println((*Foo).Bar(f)) // OK
	// The receiver here so we pass the value of the pointer
	// But the pointer is nil, so it will dereference the nil pointer and you will get an error.
	fmt.Println(Foo.Baz(*f))   // Invalid memory address error - Fail
}