Go by Example: Range Iteration
Go 1.23
The `range` keyword provides a clean way to iterate over slices, arrays, maps, strings, and channels. This example shows how to use `range` to access both indexes/keys and values.
Code
package main
import "fmt"
func main() {
// 1. Iterating over a Slice
// range returns (index, value)
nums := []int{2, 4, 6}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("Sum:", sum)
// If you need the index:
for i, num := range nums {
if num == 4 {
fmt.Println("Index of 4:", i)
}
}
// 2. Iterating over a Map
// range returns (key, value)
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
// 3. Iterating over a String
// range returns (index, rune)
// It handles Unicode characters correctly.
for i, c := range "go" {
fmt.Printf("idx: %d, char: %c\n", i, c)
}
// 4. Iterating over a Channel
// Loops until the channel is closed.
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue) // Important: close to terminate the range loop
for elem := range queue {
fmt.Println("Channel received:", elem)
}
}
Explanation
The range keyword is Go's tool for "foreach" style iteration. It works on a variety of data structures: slices, arrays, maps, strings, and channels. The syntax is consistent: for key, value := range collection.
Depending on what you are iterating over, the return values change slightly:
- Slices/Arrays: Returns
index, value. - Maps: Returns
key, value. Note that map iteration order is random. - Strings: Returns
index, rune. It decodes UTF-8 characters automatically, so the index might jump by more than 1 for multi-byte characters. - Channels: Returns
valueonly. It iterates until the channel is closed.
A common idiom in Go is using the blank identifier _ (underscore) to ignore values you don't need. For example, if you only want the values of a slice and not the indexes, you write for _, v := range slice.
Code Breakdown
10
Using the blank identifier '_'. Range returns the index first, but we don't need it here. Since Go forbids unused variables, we must assign the index to '_' to discard it.
25
Iterating over a map. This gives you both the key and the value. Remember that the iteration order for maps in Go is randomized to prevent developers from relying on a specific order.
32
Iterating over a string. 'c' is a rune (Unicode code point). If the string contained "Hello, 世界", range would correctly iterate over the Chinese characters, treating them as single units rather than raw bytes.
43
Range over a channel. This loop will block waiting for data and continue running until the 'queue' channel is explicitly closed. If you forget to close the channel, this loop could hang forever (deadlock).

