ZetCode

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.

slice_range.go
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.

array_range.go
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
array_range2.go
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.

map_range.go
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.

string_range.go
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.

channel_range.go
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.

integer_range.go
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

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Go tutorials.