For statements with
rangeclause… For each iteration, iteration values are produced as follows if the respective iteration variables are present:
Range expression 1st value 2nd value array or slice a [n]E, *[n]E, or []E index i int a[i] E string s string type index i int see below rune map m map[K]V key k K m[k] V channel c chan E, <-chan E element e E integer n integer type value i see below
How do we read this table?
Let’s look at an example for each, which I think will help clarify things.
array or slice
Assuming a is of type [n]E, *[n]E or []E, that is, an array (i.e. [3]int), a pointer to an array (i.e. *[3]int), or a slice (i.e. []int) (we can’t range over a pointer to a slice–*[]int), in the following code:
for a, b := range a {
The first value, a, will be of type int, and b will be of the element type of the array or slice (i.e. int).
For each iteration of the loop, a’s value increments, and the value of b will be the corresponding value of the array/slice.
string
Here, a’s type is also an int, and b will be a rune. There’s no direct way to reference the nth rune of a string, so this is a special case, which we’ll discuss shortly.
map
a’s type is the map key’s type, and b the map element’s type. So given a map of type map[string]int, for example, a, will be of type string, and b of type int.
channel
a is the channel element type. The two-variable form is not permitted when ranging over channels, so there is no b.
integer
As when ranging over a channel, there is no two-variable version here. The exact type of a, the first variable, depends, as we’ll see in the coming section.
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)