blob: 23f57159a7423f217e3219275a326ca47a8d5b27 [file] [view]
---
title: Range Clauses
---
Spec: https://go.dev/ref/spec#For_statements
## Summary
A range clause provides a way to iterate over an array, slice, string, map, or channel.
## Example
```go
for k, v := range myMap {
log.Printf("key=%v, value=%v", k, v)
}
for v := range myChannel {
log.Printf("value=%v", v)
}
for i, v := range myArray {
log.Printf("array value at [%d]=%v", i, v)
}
```
## Reference
If only one value is used on the left of a range expression, it is the 1st value in this table.
| Range expression | 1st value | 2nd value (optional) | notes |
| :----------------------------------------- | :------------- | :------------------- | :------------------------------------------------- |
| array or slice a `[n]E`, `*[n]E`, or `[]E` | index `i int` | `a[i]` E |
| string s string type | index `i int` | rune `int` | range iterates over Unicode code points, not bytes |
| map m `map[K]V` | key `k K` | value `m[k]` V |
| channel c chan E | element `e E` | _none_ |
## Gotchas
When iterating over a slice or map of values, one might try this:
```go
items := make([]map[int]int, 10)
for _, item := range items {
item = make(map[int]int, 1) // Oops! item is only a copy of the slice element.
item[1] = 2 // This 'item' will be lost on the next iteration.
}
```
The `make` and assignment look like they might work, but the value property of `range` (stored here as `item`) is a _copy_ of the value from `items`, not a pointer to the value in `items`. The following will work:
```go
items := make([]map[int]int, 10)
for i := range items {
items[i] = make(map[int]int, 1)
items[i][1] = 2
}
```