The range keyword in Golang allows us to iterate over the elements in numerous built-in types. We can range over numbers, slices, etc., with a simple syntax.
Range over slice
We can range over the individual elements in a slice without using the index of each element - here we use the blank identifier _ where the index would be:
package main
import "fmt"
func main() {
sum := 0
nums := []int{1, 2, 3, 4, 5, 6}
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
}
Slice with index
We can also make use of the index if we so desire:
package main
import "fmt"
func main() {
nums := []int{1, 2, 3, 4, 5, 6}
for i, num := range nums {
if num%2 == 0 {
fmt.Println("even number at index:", i, "value:", num)
}
}
}
Range over map
We can access both the keys and values of maps using range. Try running the following program multiple times:
package main
import "fmt"
func main() {
myMap := map[string]string{
"a": "apple",
"b": "banana",
"o": "orange",
}
for key, value := range myMap {
fmt.Println("key: ", key, ", value:", value)
}
}
Notice how we do not get the same output each time we run this program. This is because maps are unordered in Golang thus are not guaranteed to produce the same results via iteration.
Slices, unlike maps, are ordered and will produce the same results each time we iterate through them.
Map keys only
We can also access only the keys if we so desire:
package main
import "fmt"
func main() {
myMap := map[string]string{
"a": "apple",
"b": "banana",
"o": "orange",
}
for key := range myMap {
fmt.Println("key: ", key)
}
}
Range over string
In the same way that we can loop through a slice or array, we can loop through a string, treating the string as a read-only slice of bytes listed as runes (integers that represent Unicode code points). We can get the index of each rune and the value of each using range:
package main
import "fmt"
func main() {
sentence := "Hello Tèè!"
for i, c := range sentence {
fmt.Println("index:", i, ", rune:", c)
}
}
The output value for each rune is an integer that represents the current character in the string.
Some characters such as those with special letter formations such as è may require multiple runes to represent them.
We can see each rune by using range with the length of the string:
package main
import (
"fmt"
)
func main() {
sentence := "Hello Tèè!"
for i := range len(sentence) {
fmt.Println("index:", i, "rune:", sentence[i], ", unicode string:", string(sentence[i]))
}
}