A range loop iterates over a string, array, pointer to an array, slice, map, or receiving channel without a manual index condition. For a slice, it supplies an index and an element value; use `_` to discard the index, or omit the value if only the index matters. A receiving channel supplies only a value. section 4.1.1
Mistake: changing the value variable and expecting the collection to change. In `for _, a := range accounts { a.balance += 1000 }`, each `a` is a copy. Balances of 100, 200, and 300 remain unchanged in the slice. To update the elements, write `for i := range accounts { accounts[i].balance += 1000 }`. A classic `for` loop is useful when you need finer control over which indexes to visit. A slice of pointers is another option when shared, mutable elements are intended. section 4.1.2
for i := range accounts { #1
accounts[i].balance += 1000
}
for i := 0; i < len(accounts); i++ { #2
accounts[i].balance += 1000
}
Both loops update the slice through its index rather than modifying a copied element value. section 4.1.2
The expression after `range` is evaluated once, before iteration. If a three-element slice is appended to inside its range loop, the loop still takes three iterations: it uses the original, three-length slice value. A classic loop that checks `len(s)` on every iteration behaves differently and can keep growing indefinitely. section 4.2
That one-time evaluation has different observable effects by type:
- Channel: reassigning the channel variable inside the loop does not switch the channel being received from. section 4.2.1
- Array: ranging over an array copies it. Changing the original array during iteration does not change later values read from that copy; range over an array pointer or read the original by index when those changes must be visible. section 4.2.2
- Map: do not rely on key order, insertion order, deterministic iteration order, or seeing an entry added during iteration. section 4.7
A pointer to the wrong customer
In the illustrated `for _, customer := range customers` loop, storing `&customer` under each ID makes all three map entries point to the final customer. The address taken is that of the loop variable, not an element in the slice. Use `&customers[i]` when the map should point to the original elements; make a local copy inside the loop when it should point to separate copies. section 4.3
For a string, range supplies each rune and the starting byte index of its UTF-8 sequence. In `"hêllo"`, the indexes are 0, 1, 3, 4, and 5. Printing `s[i]` reads a byte, not the rune `ê`; use `for i, r := range s` and print `r`. Convert to `[]rune` if positions must count runes instead of bytes. section 5.2


