For statements with
range
clause… 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)