range and the copy trap, again
Walking the whole shelf — range:
for i, it := range items {
fmt.Printf("%2d. %s\n", i+1, formatItem(it))
}
range hands you each record's index (i, from 0) and value (it). Humans count from 1 — so we print i+1. Don't need the index? for _, it := range items.
But an old acquaintance lurks here. Try marking ALL books as read:
for _, it := range items {
it.Read = true // changes only the COPY!
}
// items — not a single record changed
Nothing changed. Sound familiar? It is lesson 3's copy trap, now inside a loop: range copies each element into it. You change the copy — the original on the shelf stays as it was.
The correct road is changing through the index, directly on the shelf:
for i := range items {
items[i].Read = true // the REAL element changes
}
items[i] is not a copy — it is the element itself. Memorize the pair: reading — for _, it := range; changing — for i := range + items[i].
Gotcha.
for _, it := range items { it.Read = true }compiles, runs and… does nothing. A silent bug, like the int division in lesson 6. If nothing seems to change after your loop — first check whether you are mutating the range copy.