Go by Example

Range over Iterators

Since Go 1.23, range can iterate over functions that yield values; iterators must stop when yield returns false.

Since Go 1.23, range can iterate over functions. An iter.Seq[V] iterator calls a yield function for each value; the caller uses an ordinary range loop.

When the loop stops early, yield returns false. The iterator must return immediately so it does not keep producing values.

package main
 
import (
    "fmt"
    "iter"
)
 
func Count(n int) iter.Seq[int] {
    return func(yield func(int) bool) {
        for i := 0; i < n; i++ {
            if !yield(i) {
                return
            }
        }
    }
}
 
func main() {
    for n := range Count(5) {
        if n == 3 {
            break
        }
        fmt.Println(n)
    }
}

In production

Iterators can generate values without first allocating an intermediate slice, which helps with large or streamed inputs. This feature and the standard iter package require Go 1.23 or later. Respecting yield's false result is essential for early exit and cleanup.

Enjoyed this? Get more software craft delivered to your inbox.