The range Keyword
In this page:
Ranging Over a Slice
range on a slice or array gives you both the index and the value at each step, letting you avoid manually managing an index variable and bounds checks.
Example: Ranging Over a Slice
package main
import "fmt"
func main() {
fruits := []string{"apple", "banana", "cherry"}
for i, fruit := range fruits {
fmt.Println(i, fruit)
}
}
Login to try C/C++/Java/PHP code in the editor
Ignoring the Index or Value
If you only care about the value and not the index (or vice versa), the blank identifier _ discards the part you don't need, satisfying Go's rule that every declared variable must be used.
Note: Go's compiler rejects a declared-but-unused variable, so _ is essential when you only need one of the two range values.
Example: Ignoring the Index or Value
package main
import "fmt"
func main() {
fruits := []string{"apple", "banana", "cherry"}
for _, fruit := range fruits {
fmt.Println("fruit:", fruit)
}
}
Login to try C/C++/Java/PHP code in the editor
Ranging Over a Map
range on a map yields each key-value pair, but the order of iteration is deliberately randomized by the Go runtime every time the program runs, which prevents code from accidentally depending on a specific order.
Note: Map iteration order is intentionally randomized by Go each run -- never rely on it being consistent.
Example: Ranging Over a Map
package main
import "fmt"
func main() {
ages := map[string]int{"Amit": 30, "Sara": 25}
total := 0
for _, age := range ages {
total += age
}
fmt.Println("total age:", total)
}
Login to try C/C++/Java/PHP code in the editor
Ranging Over a String
range on a string decodes it as UTF-8, yielding the byte index and the rune (full character) at that position -- correctly handling multi-byte characters, unlike a plain byte-index loop.
Example: Ranging Over a String
package main
import "fmt"
func main() {
for i, r := range "Go!" {
fmt.Printf("%d: %c\n", i, r)
}
}
Login to try C/C++/Java/PHP code in the editor
- Assuming the range loop variable is a fresh variable each iteration in older Go versions -- pre-1.22 it was reused, causing common closure-capture bugs.
- Ignoring the index/key that range provides when only the value is needed, instead of using the blank identifier _ to discard it.
- Modifying a slice's length while ranging over it, which does not change how many iterations the already-started range performs.
- range iterates over arrays, slices, strings, maps, and channels, adapting its output to each type.
- For slices/arrays, range yields index and value; for maps, key and value; for strings, byte index and rune.
- Use the blank identifier _ to ignore a value you don't need from range.
- Since Go 1.22, each range iteration gets its own fresh loop variable, avoiding an old class of closure bugs.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: