Go: Range loops (for each loops) explained
Range statements iterate over slices, arrays, strings, maps or channels.
Basics
a := []string{"Foo", "Bar"}
for i, s := range a {
fmt.Println(i, s)
}
0 Foo
1 Bar
- The range expression,
a
, is evaluated once before beginning the loop. - The iteration values are assigned to the respective iteration variables,
i
ands
, as in an assignment statement. - The second iteration variable is optional.
- If a slice or map is
nil
, the number of iterations is 0.
Strings
For a string, the loop iterates over Unicode code points.
for i, ch := range "日本語" {
fmt.Printf("%#U starts at byte position %d\n", ch, i)
}
U+65E5 '日' starts at byte position 0
U+672C '本' starts at byte position 3
U+8A9E '語' starts at byte position 6
- The index is the first byte of a UTF-8-encoded code point; the second value, of type
rune
, is the value of the code point. - For an invalid UTF-8 sequence, the second value will be 0xFFFD, and the iteration will advance a single byte.
Maps
The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next.
m := map[string]int{
"one": 1,
"two": 2,
"three": 3,
}
for k, v := range m {
fmt.Println(k, v)
}
two 2
three 3
one 1
- If a map entry that has not yet been reached is removed during iteration, this value will not be produced.
- If a map entry is created during iteration, that entry may or may not be produced.
Channels
For channels, the iteration values are the successive values sent on the channel until closed.
ch := make(chan int)
go func() {
ch <- 1
ch <- 2
ch <- 3
close(ch)
}()
for n := range ch {
fmt.Println(n)
}
1
2
3
For a nil
channel, the range loop blocks forever.
Comments
Be the first to comment!