Go core · 3 MIN READ

Nothing is uninitialised

Predict the value of any declared variable before it is assigned.

Every Go variable starts at its type's zero value: 0 for numbers, "" for strings, false for booleans, and nil for pointers, slices, maps, channels, functions and interfaces. A declaration gives you a defined value immediately.

A struct starts with every field at its own zero value. Design that state to be useful when possible: counters and slices work naturally, while a map field still needs initialization before a write. A New function is useful when the type requires setup that its zero value cannot provide.

SEE THE IDEA

A value exists before you assign one

  1. 01

    Numbers

    go
    var count int

    Starts at 0

  2. 02

    Text and flags

    go
    var name string

    Starts at ""; bool starts at false

  3. 03

    References

    go
    var p *int

    Pointers, slices, maps and channels start nil

The zero value comes from the type, not from leftover memory.

In practice

Design a type so its zero value is useful when possible. A zero counter can be incremented and a nil slice can be appended to. A nil map can be read, but needs allocation before a write; a nil channel blocks both sends and receives.

Watch out

Zero does not mean ready for every operation. Check the rules of the specific type before using it.

Official reference ↗

Read and predict

go
package main

import "fmt"

type Counter struct {
	Total int
	Label string
	Tags  []string
}

func main() {
	var c Counter
	fmt.Printf("%d %q %v %d\n", c.Total, c.Label, c.Tags == nil, len(c.Tags))
}

What does this print, and why does len work on a nil slice?

Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.