range over a map — the order is RANDOM
To visit every entry, use range — same keyword as for slices, but you get the key and the value:
counts := map[string]int{"history": 2, "science": 5, "poetry": 1}
for category, n := range counts {
fmt.Printf("%s: %d\n", category, n)
}
(That map[string]int{...} form is a map literal — a quick way to build a map already filled in.)
Now the gotcha — and we're going to prove it, not just claim it. Range the same map twice in one program:
func main() {
counts := map[string]int{
"fantasy": 3, "history": 2, "science": 5,
"poetry": 1, "biography": 4, "travel": 2,
}
fmt.Print("Pass 1:")
for k := range counts {
fmt.Print(" ", k)
}
fmt.Println()
fmt.Print("Pass 2:")
for k := range counts {
fmt.Print(" ", k)
}
fmt.Println()
}
Run it. Here is a real run:
Pass 1: fantasy history science poetry biography travel
Pass 2: science poetry biography travel fantasy history
Look carefully: Pass 1 and Pass 2 differ — in the same program, on the same map, with nothing changed in between. Run the program again and both lines come out in yet another order. The order is not alphabetical, not insertion order, not anything you can predict.
Why does Go do this on purpose? Because a map is a hash table — it has no inherent order. Early Go had an accidental, stable-ish order, and people started depending on it ("the first key is always X"). That code broke the moment the map grew and Go rearranged its buckets. So Go now randomizes the start point of every range — deliberately — to make sure nobody can lean on an order that was never promised. It's a feature: it turns a "works on my machine" bug into one that shows up on the very first run.
What this means for you:
- Never rely on map order.
for k := range mgives keys in a random order every time. - Use a map when you look things up by key or count/group — the order of the entries doesn't matter.
- When you do need a fixed order (say, printing categories alphabetically), collect the keys into a slice and sort that. Sorting is a job for the Algorithms course — for now, just know the map itself won't do it.
Gotcha (the test that passes today and fails Friday). If you write a test that expects map output in a specific order, it will pass sometimes and fail other times — the classic flaky test. The fix is never "run it again"; it's to stop depending on order (compare the counts, not the printed line). Keep this in mind — we meet automated tests in lesson 13.
Next: put the map to work in YOUR app — count items by category, and find one instantly by title.