Skip to content

Go Range

The range keyword in Go provides a convenient way to iterate over elements in various data structures like arrays, slices, strings, maps, and channels within a for loop.

When iterating, range typically returns two values: the index/key and the element/value. You can choose to receive both, only the first, or ignore both.

Range Expression Over1st Value2nd Value (Optional)
Array or Slice aIndex i (int)Element a[i] (type of element)
String sIndex i (int, byte index)Rune r (int32, Unicode code point)
Map mKey k (type of key)Value v (type of value)
Channel cElement e (type of element)(No second value)

If you only need the first value (e.g., index or key), you can omit the second:

for i := range numbers { // i gets the index
// ...
}
for key := range countryCapitalMap { // key gets the map key
// ...
}

If you only need the second value (e.g., the element itself), you can use the blank identifier _ to ignore the first value:

sum := 0
for _, num := range numbers { // Ignore index, get number
sum += num
}

If you don’t need either value (perhaps just to count iterations), you can ignore both, although this is less common:

count := 0
for range numbers { // Ignore both index and value
count++
}

Here’s an example demonstrating range with slices, maps, and strings:

package main
import "fmt"
func main() {
// --- Slice Example ---
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
fmt.Println("Iterating over slice (index and value):")
for i, num := range numbers {
fmt.Printf("Slice index %d has value %d\n", i, num)
}
fmt.Println("\nIterating over slice (value only):")
sum := 0
for _, num := range numbers {
sum += num
}
fmt.Printf("Sum of numbers: %d\n", sum)
// --- Map Example ---
countryCapitalMap := map[string]string{
"France": "Paris",
"Italy": "Rome",
"Japan": "Tokyo",
}
fmt.Println("\nIterating over map (key and value):")
for country, capital := range countryCapitalMap {
fmt.Printf("Capital of %s is %s\n", country, capital)
}
fmt.Println("\nIterating over map (key only):")
for country := range countryCapitalMap {
fmt.Printf("Country: %s, Capital: %s\n", country, countryCapitalMap[country])
}
// --- String Example (iterating over runes) ---
fmt.Println("\nIterating over string (runes):")
for index, runeValue := range "Go语言" {
fmt.Printf("Byte index: %d, Rune: %c (Unicode: %U)\n", index, runeValue, runeValue)
}
}

When the above code is compiled and executed, it produces the following result (map iteration order may vary):

Iterating over slice (index and value):
Slice index 0 has value 0
Slice index 1 has value 1
Slice index 2 has value 2
Slice index 3 has value 3
Slice index 4 has value 4
Slice index 5 has value 5
Slice index 6 has value 6
Slice index 7 has value 7
Slice index 8 has value 8
Iterating over slice (value only):
Sum of numbers: 36
Iterating over map (key and value):
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Iterating over map (key only):
Country: France, Capital: Paris
Country: Italy, Capital: Rome
Country: Japan, Capital: Tokyo
Iterating over string (runes):
Byte index: 0, Rune: G (Unicode: U+0047)
Byte index: 1, Rune: o (Unicode: U+006F)
Byte index: 2, Rune: 语 (Unicode: U+8BED)
Byte index: 5, Rune: 言 (Unicode: U+8A00)

Important Note: When ranging over slices or arrays, range operates on a copy of the value. If you need to modify the original elements, use the index to access them: numbers[i] = newValue.

For strings, range iterates over Unicode code points (runes), not bytes. The first value returned is the starting byte index of the rune.