The types of iteration variables

June 13, 2024

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)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Iteration over arrays and slices

For statements with range clause … For an array, pointer to array, or slice value a, the index iteration values are produced in increasing order, starting at element index 0. If at most one iteration variable is present, the range loop produces iteration values from 0 up to len(a)-1 and does not index into the array or slice itself. For a nil slice, the number of iterations is 0. From this above paragraph, we can be assured that ranging over an array, pointer to array, or slice, will operate in a defined order–from index 0, upward.


Rangeable values

For statements with range clause A “for” statement with a “range” clause iterates through all entries of an array, slice, string or map, values received on a channel, or integer values from zero to an upper limit [Go 1.22]. Wow, that’s a long list. And it’s about to get longer! Go 1.23 is scheduled to add iterator functions to that list, but we’ll talk about that when the time comes (in August).


For statements with range clause

Yesterday we saw some high-level examples of range statements. Let’s start into some of the details now. For statements with range clause … For each entry it assigns iteration values to corresponding iteration variables if present and then executes the block. RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression . The formal definition there is pretty straight forward. But there are a number of nuances, which we’ll cover over the next few days.

Get daily content like this in your inbox!

Subscribe