Maps
A map is Go's built-in key/value lookup table — the data structure you reach for whenever you need to find something by name rather than by position. You'll learn to create maps, read and write entries, safely check whether a key exists with the "comma ok" idiom, delete keys, and tally data with the classic counting pattern.
Learn Maps in our free Go course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free Go course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Creating & Accessing
A map's type is — for example . Build one with make or a literal, then read and write entries with square brackets. A crucial Go quirk: reading a key that isn't there does not error — it returns the value type's zero value ( 0 , "" , false ). That's convenient, but it's why you need the comma-ok check below.
2️⃣ comma-ok & delete
Because a missing key returns a zero value, you can't tell "the value really is 0" from "the key isn't here" by reading alone. The comma-ok form solves this: value, ok := m[key] gives you the value and a boolean that's true only when the key exists. Remove an entry with the built-in delete(m, key) , which is safe even if the key was never there.
3️⃣ Ranging & the Count Pattern
You range over a map to get keys and values, but remember the order is randomized on every run — never depend on it. For stable output, collect the keys into a slice and sort them. The single most common map idiom is counting: counts[w]++ works even for a brand-new key because the missing value starts at the zero value 0 .
Your turn — build a small price list and read one back.
Now use the comma-ok idiom to check whether a user is registered.
These lines count a key twice, but they're scrambled. Put them in order so the program prints 2 (assume a func main wraps them).
Why: the map must exist before any key can be incremented. The first m["a"]++ turns the missing-key zero into 1; the second makes it 2. Printing m["a"] last yields 2. Both increments must precede the print.
Predict the output before you reveal the answer.
{'m := map[string]int ; fmt.Println(m["x"])'}
0 — reading a missing key returns the value type's zero value, which is 0 for int. No error, no panic.
{'m := map[string]int ; _, ok := m["a"]; fmt.Println(ok)'}
true — the key "a" exists (its value just happens to be 0), so the comma-ok boolean is true.
{'m := map[string]int ; m["go"]++; m["go"]++; fmt.Println(m["go"])'}
2 — the first increment takes the implicit 0 to 1, the second to 2. This is the counting idiom in action.
Go returns the value type's zero value instead, which keeps lookup code simple. Use the comma-ok form ( v, ok := m[k] ) when you must know whether the key actually exists.
Only comparable types: strings, numbers, booleans, arrays, and structs of comparable fields. Slices, maps, and functions can't be keys because they aren't comparable with == .
Range the map to collect keys into a slice, then call sort.Strings (or sort.Ints ). Iterate that sorted slice for deterministic output.
Range over the word's runes and count each letter into a , then print the tally for the letter 'l'. Write it yourself and match the example output.
Practice quiz
What is the type syntax for a Go map from string keys to int values?
- map<string,int>
Go maps are written map[KeyType]ValueType, e.g. map[string]int.
What does a map return when you read a key that is absent?
- An error
- nil
- The value type's zero value
- A panic
Answer: The value type's zero value. A missing key returns the value type's zero value — never an error.
Which form distinguishes 'absent' from 'present but zero'?
The comma-ok form v, ok := m[k] sets ok=false when the key is missing.
How do you remove an entry from a map?
- remove(m, k)
- m.delete(k)
- delete(m, k)
Answer: delete(m, k). The built-in delete(m, k) removes the entry for key k.
What does len(m) return for a map?
- The capacity
- The number of key/value pairs
- Always 0
- The size in bytes
Answer: The number of key/value pairs. len(m) counts how many key/value pairs the map currently holds.
What is the iteration order when you range over a map?
- Insertion order
- Sorted by key
- Random / unspecified
- Reverse insertion
Answer: Random / unspecified. Map iteration order is randomized; sort the keys yourself for stable output.
Which built-in creates an empty, usable map?
- new(map)
make(map[K]V) creates an initialized map ready for writes.
What does m[k]++ do when k is not yet in the map?
- Panics
- Starts from the zero value, so becomes 1
- Does nothing
- Returns an error
Answer: Starts from the zero value, so becomes 1. Reading a missing int key yields 0, so m[k]++ cleanly sets it to 1 — handy for tallies.
What happens if you write to a nil map?
- It is created
- It panics
- It is ignored
- It returns false
Answer: It panics. Writing to a nil map panics; initialize with make or a literal first.
To print map entries in a stable order, you should:
- Use a special flag
- Collect keys, sort them, then range over keys
- Nothing — it is already sorted
- Convert to a slice automatically
Answer: Collect keys, sort them, then range over keys. Gather the keys into a slice, sort them, then iterate in that order.