Go language Range

In Go, the range keyword is used in for loops to iterate over elements of arrays, slices, channels, or maps. For arrays and slices, it returns the index of the element and the value corresponding to that index; for maps, it returns key-value pairs.

The range format of the for loop can iterate over slices, maps, arrays, strings, and more. The format is as follows:

for key, value := range oldMap {
    newMap[key] = value
}

The key and value in the above code can be omitted.

If you only want to read the key, the format is as follows:

for key := range oldMap

Or like this:

for key, _ := range oldMap

If you only want to read the value, the format is as follows:

for _, value := range oldMap

Example

Arrays and Slices

Iterating over a simple slice,2**%dThe result is the corresponding power of 2:

Example

package main

import "fmt"

// Declare a slice containing powers of 2
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
   // Iterate over the pow slice, i is the index, v is the value
   for i, v := range pow {
      // Print 2 raised to the power of i equals v
      fmt.Printf("2**%d = %d\n", i, v)
   }
}

The output of the above example is:

2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128

String

When range iterates over a string, it returns the index of each character and its Unicode code point (rune).

Example

package main

import "fmt"

func main() {
    for i, c := range "hello" {
        fmt.Printf("index: %d, char: %c\n", i, c)
    }
}

The output of the above example is:

index: 0, char: h
index: 1, char: e
index: 2, char: l
index: 3, char: l
index: 4, char: o

Map

The range format of the for loop can omit key and value, as in the following example:

Example

package main

import "fmt"

func main() {
    // Create an empty map, key is of int type, value is of float32 type
    map1 := make(map[int]float32)
   
    // Add key-value pairs to map1
    map1[1] = 1.0
    map1[2] = 2.0
    map1[3] = 3.0
    map1[4] = 4.0
   
    // Iterate over map1, reading key and value
    for key, value := range map1 {
        // Print key and value
        fmt.Printf("key is: %d - value is: %f\n", key, value)
    }

    // Iterate over map1, reading only key
    for key := range map1 {
        // Print key
        fmt.Printf("key is: %d\n", key)
    }

    // Iterate over map1, reading only the value
    for _, value := range map1 {
        // Print the value
        fmt.Printf("value is: %f\n", value)
    }
}

The output of the above example is:

key is: 4 - value is: 4.000000
key is: 1 - value is: 1.000000
key is: 2 - value is: 2.000000
key is: 3 - value is: 3.000000
key is: 1
key is: 2
key is: 3
key is: 4
value is: 1.000000
value is: 2.000000
value is: 3.000000
value is: 4.000000

Channel

range iterates over values received from a channel until the channel is closed.

Example

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    close(ch)
   
    for v := range ch {
        fmt.Println(v)
    }
}

The output of the above example is:

1
2

Ignore the value

When iterating, you can use_to ignore the index or value.

Example

package main

import "fmt"

func main() {
    nums := []int{2, 3, 4}
   
    // Ignore the index
    for _, num := range nums {
        fmt.Println("value:", num)
    }
   
    // Ignore the value
    for i := range nums {
        fmt.Println("index:", i)
    }
}

The output of the above example is:

value: 2
value: 3
value: 4
index: 0
index: 1
index: 2

Other

range iterates over other data structures:

Example

package main
import "fmt"
func main() {
    // Here we use range to sum a slice. Using an array is very similar.
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)
    // Using range on an array passes in two variables: the index and the value. In the example above, we didn't need the element's index, so we omitted it with the blank identifier "_". Sometimes we do need to know its index.
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }
    // range can also be used on map key-value pairs.
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }

    // range can also be used to enumerate Unicode strings. The first parameter is the character's index, and the second is the character (the Unicode value) itself.
    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

The output of the above example is:

sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111
other extensions