Skip to content

Latest commit

 

History

History
69 lines (56 loc) · 1.89 KB

zero-value.md

File metadata and controls

69 lines (56 loc) · 1.89 KB

Originate Guides - Go - Making the zero value useful

Go tries hard to make the zero value of variables useful. For example, an empty string is a better zero value for strings than nil, because you can use empty strings like any other string without having to litter your code base with nil checks. When used, it behaves neutral. That's all you need in most situations. Go cannot do this for your own custom types, so it has to use nil as their zero value. This doesn't mean that nil is always the best zero value, though. Use the null object pattern to save yourself and your users from having to litter their code with nil checks. This can be done via factory functions. The Go library provides null implementations for many of its elements, for example:

Example: Let's say cars have doors, but some toy cars don't. We want to use doors in our code without having to check each time whether a car has doors.

type Car struct {
  door Door
}

type Door interface {
  open() error
}

// NoDoor is a Door implementation that represents no door.
// You can use it like a normal door, it simply does nothing.
type NoDoor struct{}

func (d NoDoor) open() error {
  return nil
}

// NewCar creates a new car instance with the given door.
// If no door is given, it creates a car with a NoDoor.
func NewCar(d Door) Car {
  if d == nil {
  	d = NoDoor{}
  }
  return Car{door: d}
}

Let's create a car with no door, for example in a test where we don't care about the door:

c := NewCar(nil)

Now our code can simply use the door, whether it is there or not:

c.door.open()

Instead of pervasive nil checks for every attribute each time we call it:

if c.Door != nil {
  c.door.open()
}