Range
Range iterates over elements in a variety of data structures. It's commonly used with for loops to iterate over slices, arrays, maps, strings, and channels.
Key Points
- Range creates copies of values, not references to the original elements
- Use
_to ignore values you don't need (blank identifier) - Map iteration order is randomized for security reasons
- Range on a nil slice or map is safe and produces zero iterations
- Modifying a slice during range iteration can lead to unexpected behavior
- For strings, the first value is the byte index, not character index
Range Over Slices
Range provides both the index and value for each element:
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
sum := 0
// Range over slice with index and value
for i, num := range nums {
sum += num
fmt.Printf("index: %d, value: %d\n", i, num)
}
fmt.Println("sum:", sum)
// Range with index only (ignore value)
for i := range nums {
fmt.Println("index:", i)
}
}index: 0, value: 2
index: 1, value: 3
index: 2, value: 4
sum: 9
index: 0
index: 1
index: 2Range Over Maps and Strings
Range on maps iterates over key-value pairs, and on strings it iterates over Unicode code points:
package main
import "fmt"
func main() {
// Range over map
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
// Range over map keys only
for k := range kvs {
fmt.Println("key:", k)
}
// Range over string (Unicode code points)
for i, c := range "go" {
fmt.Println(i, c)
}
}a -> apple
b -> banana
key: a
key: b
0 103
1 111Range Patterns
| Pattern | Example | Description |
|---|---|---|
for i, v := range slice | for i, v := range nums | Get both index and value |
for i := range slice | for i := range nums | Get index only |
for _, v := range slice | for _, v := range nums | Get value only (ignore index) |
for k, v := range map | for k, v := range m | Get map key and value |
for k := range map | for k := range m | Get map keys only |
for i, c := range string | for i, c := range "hello" | Get byte index and Unicode code point |
for v := range channel | for v := range ch | Receive values from channel until closed |
Range Behavior by Type
| Type | First Value | Second Value | Notes |
|---|---|---|---|
| Array/Slice | index (int) | value (element copy) | Index starts at 0 |
| String | index (int) | rune (int32) | Index is byte position, value is Unicode code point |
| Map | key | value | Iteration order is random |
| Channel | value | n/a | Blocks until value received or channel closed |