Go range
last modified August 30, 2026
The range clause makes it easy to visit the elements of a
collection. It is used with for, and it produces an index and a
value for arrays, slices, and strings, a key and a value for maps, or values
received from channels.
The loop variables are local to the loop. Use _ when one of the
values is not needed. Map iteration order is intentionally unspecified, and a
channel range ends only after the channel is closed.
Go range slice
Slices are the most common collection used with range. The first
variable is the zero-based index and the second is a copy of the element.
package main
import "fmt"
func main() {
vals := []string{"red", "green", "blue"}
for idx, val := range vals {
fmt.Printf("%d: %s\n", idx, val)
}
}
$ go run slice_range.go 0: red 1: green 2: blue
Go range array
The following example uses range to iterate over a Go array.
package main
import "fmt"
func main() {
vals := [...]int{5, 4, 3, 2, 1}
for idx, e := range vals {
fmt.Println("element", e, "at index", idx)
}
}
We iterate over an array of integer values.
$ go run array_range.go element 5 at index 0 element 4 at index 1 element 3 at index 2 element 2 at index 3 element 1 at index 4
package main
import "fmt"
func main() {
vals := [...]int{5, 4, 3, 2, 1}
for _, e := range vals {
fmt.Printf("%d ", e)
}
fmt.Println("\n******************")
for idx, _ := range vals {
fmt.Printf("%d ", idx)
}
fmt.Println("\n******************")
for idx := range vals {
fmt.Printf("%d -> %d\n", idx, vals[idx])
}
}
This example shows that the index or the element in the
iteration can be skipped by using _. The one-variable form
for idx := range vals iterates over indexes without creating a
value variable.
for idx := range vals {
fmt.Printf("%d -> %d\n", idx, vals[idx])
}
In this form, we are iterating over indexes.
Go range map
The following example uses range to iterate over a Go map.
package main
import "fmt"
func main() {
data := map[string]string{
"de": "Germany",
"it": "Italy",
"sk": "Slovakia",
}
for k, v := range data {
fmt.Println(k, "=>", v)
}
fmt.Println("----------------------")
for k := range data {
fmt.Println(k, "=>", data[k])
}
}
The example iterates over a country map, where the keys and the values are strings.
The output order is not guaranteed. A program must not rely on a particular order when ranging over a map. Sort the keys first when deterministic output is required.
$ go run map_range.go de => Germany it => Italy sk => Slovakia ---------------------- de => Germany it => Italy sk => Slovakia
Go range string
The following example uses range to iterate over a Go string.
package main
import "fmt"
func main() {
s := "合気道"
for idx, e := range s {
fmt.Printf("%d %c\n", idx, e)
}
fmt.Println()
}
In the code example, we iterate over Go runes. The index is the byte offset of the rune in the UTF-8 string, not its character number.
$ go run string_range.go 0 合 3 気 6 道
This is the output. Each of these runes is encoded using three bytes, so their
byte offsets are 0, 3, and 6. Invalid UTF-8 bytes are reported as
utf8.RuneError and advance by one byte.
Go range channel
The following example uses range to receive values from a Go channel. The sender must close the channel; otherwise the range loop waits forever after the last value.
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
ch <- 5
ch <- 6
ch <- 7
close(ch)
}()
for n := range ch {
fmt.Println(n)
}
}
In the code example, we iterate over values sent through the channel. The channel is closed after the sender has sent all three values.
$ go run channel_range.go 5 6 7
Go range integer
Since Go 1.22, an integer can be used directly with range. The
loop runs from zero up to, but not including, the integer.
package main
import "fmt"
func main() {
for n := range 3 {
fmt.Println(n)
}
}
$ go run integer_range.go 0 1 2
Source
The Go Programming Language Specification
In this article we have covered for range forms in Golang.
Author
List all Go tutorials.