Skip to content
Daily Dev Tip

This tip lives in your new tab — for free.

Install for Chrome →
GO

Write custom iterators with range-over-func (Go 1.23+)

internal/tree/iter.go
go
import "iter"

func (t *Tree[V]) All() iter.Seq[V] {
    return func(yield func(V) bool) {
        var walk func(n *node[V]) bool
        walk = func(n *node[V]) bool {
            if n == nil {
                return true
            }
            return walk(n.left) && yield(n.value) && walk(n.right)
        }
        walk(t.root)
    }
} // usage: for v := range tree.All() { ... }

Go 1.23 lets functions of type `iter.Seq[V]` be consumed by `for range`. You return a function that calls `yield` for each element; returning `false` from `yield` (a `break` at the call site) stops iteration, so you propagate it up the walk. This exposes internal structures — trees, paginated APIs, streams — through the standard `for range` syntax without allocating an intermediate slice or exposing your node types.

go1.23iteratorsgenericsstdlib