Rangeable values

June 6, 2024

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 now, let me just briefly show you an example of what each of these looks like, then we’ll continue talking about the details of how they work.

  • Range over an array or slice:

    for _, x := range []int{1,2,3} { // Where list is of array or slice type
    	fmt.Println(x)
    }
    

    prints:

    1
    2
    3
    
  • Range over a string

    for _, x := range "Hello, 世界" {
    	fmt.Println(string(x))
    }
    

    prints:

    H
    e
    l
    l
    o
    ,
    
    世
    界
    
  • Range over a map

    for k, v := range map[string]string{"cow": "moo", "chicken": "cluck"} {
    	fmt.Println(k, v)
    }
    

    prints:

    cow moo
    chicken cluck
    

    or (because a map’s order is undefined):

    chicken cluck
    cow moo
    
  • values received on a channel

    ch := make(chan int, 3)
    ch <- 10
    ch <- 20
    ch <- 33
    close(ch)
    
    for x := range ch {
    	fmt.Println(x)
    }
    

    prints:

    10
    20
    30
    
  • integer values from zero to an upper limit (added in Go 1.22)

    for x := range 5 {
    	fmt.Println(x)
    }
    

    prints:

    0
    1
    2
    3
    4
    

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


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.


The types of iteration variables

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?


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.

Get daily content like this in your inbox!

Subscribe