Limited Offer
60% OFF on all plans!

Iterators and Generators in Go

Learn iteration in Go: for-range over collections and channels, custom iteration patterns, and generator-style sequences using channels.

Iteration in Go

Go has no separate iterator protocol like some languages. Instead, you use `for range` over built-in types: slices, maps, strings, and channels. Ranging over a channel is pull-based: the consumer receives values one at a time, and the producer can run in another goroutine. That gives you lazy, on-demand flow similar to generators.

1. for range over Slice

Iterate elements, index, or both.

2. for range over Channel

Consume values until the channel is closed.

Custom Iteration

When you need custom iteration logic—for example, filtering, stepping, or producing values from a function—you can expose a channel that callers range over, or provide a callback that your function invokes for each item.

1. Function that Returns a Channel

Producer goroutine sends values and closes.

Custom Iterators (Go 1.23+)

Go 1.23 added **range over function types**: you can write `for v := range myFunc` when `myFunc` is an iterator function that accepts a **yield** callback and calls it for each value. The standard library package `iter` defines `Seq[V]` and `Seq2[K,V]` for these iterator types. If `yield` returns `false`, the iterator should stop. Your module must use Go 1.23 or later (`go 1.23` in `go.mod`) to use this feature.

1. Range over an Iterator Function

Function that takes yield and is used with for range.

2. iter with slices and maps

Use slices.Values, maps.Keys, and maps.Values as iterators.

Generator-Style Pattern

In Go, a "generator" is usually a function that starts a goroutine, returns a channel, and sends values on that channel. The consumer pulls values with `for range`. Execution is lazy: values are produced only when the consumer is ready to receive.

1. Basic Generator

Yield a sequence of values from a goroutine.

Lazy and Bounded Sequences

Channel-based producers can generate values on demand without storing the whole sequence in memory. For unbounded or long-running streams, the producer should close the channel when done or respect a cancellation signal (e.g. context) so the consumer can stop.

1. Unbounded ID Generator

Infinite sequence; consumer decides when to stop.

2. Batch (Chunk) Iteration

Process a slice in fixed-size chunks.

Pitfalls and Best Practices

Generator-style code that uses channels and goroutines must close channels when production is finished and avoid leaving producer goroutines blocked forever. Prefer closing the channel from the producer so that consumers can always detect the end of the stream.

1. Close from Producer, Receive in Consumer

Single producer closes; consumer ranges until close.