Go - for ... range

Intro

for ... range clause can be used to iterate 5 types of variables: array, slice, string, map and channel, and the following sheet gives a summary of the items of for ... range loops:

Type1st Item2nd Item
Arrayindexvalue
Sliceindexvalue
Stringindex (rune)value (rune)
Mapkeyvalue
Channelvalue

Example - Iterating on slice

package main

import "fmt"

func main() {
  s := [] {1,2,3}
  
  for i,v := range s {
    fmt.Printf("index = %d, value = %d\n", i,v)
  }
}

Example - Skipping index or value with _

If the program doesn’t need the first item, a blank identifier should occupy the position:

package main

import "fmt"

func main() {
  for _, v := range []int{1, 2, 3} {
    fmt.Println(v)
  }
}

The output is:

  1
  2
  3

Example - Only get index and skip value completely

For array, slice, string and map, if you don’t care about the second item, you can omit it. E.g.:

Example - on slice

    for i := range s {
        fmt.Println(i)
    }

Example - iterating on map keys

package main

import "fmt"

func main() {
  m := map[string]struct{} {
    "alpha": struct{}{},
    "beta": struct{}{},
  }
  for k := range m {
    fmt.Println(k)
  }
}

The running result is like this:

  alpha
  beta

Example - close operation can end for…range

For channel type, the close operation can cause for ... range loop exit. See the following code:

package main

import "fmt"

func main() {
  ch := make(chan int)
  go func(chan int) {
    for _, v := range []int{1, 2} {
      ch <- v
    }
    close(ch)
  }(ch)

  for v := range ch {
    fmt.Println(v)
  }
  fmt.Println("The channel is closed.")
}

Check the outcome:

  1
  2
  The channel is closed.

We can see close(ch) statement in another goroutine make the loop in main goroutine end.

References https://github.com/NanXiao/golang-101-hacks


See also