Skip to main content
eLearner.app
Module 2 · Lesson 3 of 58/50 in the course~10 min
Module lessons (3/5)

for...range

for ... range is the idiomatic way to iterate over collections: slices, arrays, maps, strings and channels. The syntax changes slightly depending on the collection, but the base pattern is always the same: for key, value := range coll { ... }.

Range on slices and arrays

Returns index and copy of the value:

Go
nums := []int{10, 20, 30}
for i, v := range nums {
    fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30

Often one of the two is enough:

Go
// solo indice
for i := range nums { _ = i }

// solo valore (ignora indice con _)
for _, v := range nums { _ = v }

Range on a map

Returns key and value:

Go
prices := map[string]int{"pane": 2, "latte": 3, "vino": 8}
for k, v := range prices {
    fmt.Println(k, v)
}

Range on a string: runes, not bytes

for i, r := range s iterates per Unicode code point (rune), not per byte. The index i is the byte offset of the start of the rune.

Go
for i, r := range "èé" {
    fmt.Printf("%d %c (%U)\n", i, r, r)
}
// 0 è (U+00E8)
// 2 é (U+00E9)

To iterate per byte use classic indexing:

Go
s := "ciao"
for i := 0; i < len(s); i++ {
    fmt.Println(s[i])  // byte (uint8)
}

Range on a channel

Iterates until the channel is closed:

Go
ch := make(chan int)
go func() {
    for i := 0; i < 3; i++ { ch <- i }
    close(ch)
}()
for v := range ch {
    fmt.Println(v)
}

We will dig deeper in the Concurrency module.

Try it

Exercise#go.m2.l3.e1
Attempts: 0Loading…

Print index and value of every element of nums using for-range.

Loading editor…

Solution available after 3 attempts

Exercise#go.m2.l3.e2
Attempts: 0Loading…

Sum into total all values of nums ignoring the index.

Loading editor…
Show hint

Use `_` to discard the index.

Solution available after 3 attempts

Quiz#go.m2.l3.e3
Ready

What does the first variable in `for k, v := range m` represent when m is a map?

Go
m := map[string]int{"a": 1, "b": 2}
for k, v := range m { fmt.Println(k, v) }
Answer options

Recap

  • for k, v := range coll with clear scope: discard with _ what you do not use.
  • Slice/array: index + COPY of the value. To mutate, index.
  • Map: key + value, order randomised on every run.
  • String: range iterates per rune (code point), not per byte.
  • Channel: iterates while the channel is open; closed with close().