Slices, maps and strings · 3 MIN READ

Reading a missing key is fine, writing to a nil map is not

Use comma-ok, and know which map operation panics.

Reading a key that is absent returns the value type's zero value, with no error. That is why comma-ok exists: v, ok := m[k] distinguishes "absent" from "present and zero".

The asymmetry to remember: reading from a nil map is legal and returns zero values, but writing to one panics. A map must be made before it can be written.

SEE THE IDEA

Reading and writing have different requirements

  1. 01

    Nil map

    go
    var m map[string]int

    Reads return the value type zero

  2. 02

    Absent key

    go
    m["missing"]

    Also returns zero

  3. 03

    Allocated map

    go
    m = make(map[string]int)

    Writes are now permitted

A safe read does not imply that a map is allocated for writes.

In practice

Initialize a map at the point where a function takes responsibility for storing entries. Use the two-result lookup when an absent key must be distinguished from a stored zero. Deleting a key from a nil map is safe, but assignment to a nil map panics.

Watch out

Maps are not safe for unsynchronized concurrent reads and writes. Protect access or transfer ownership.

Official reference ↗

Work through the exercise

go
package main

// countWords returns how many times each word appears.
func countWords(words []string) map[string]int {
	var counts map[string]int
	for _, word := range words {
		counts[word]++
	}
	return counts
}

func main() {}
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.