An iterator lets a consumer retrieve sequence values one at a time through a common interface. In Go, a custom iterator can be ranged over like a slice while hiding whether values come from a slice, a channel, or sequential or concurrent work. Returning an iterator decouples callers from the producer’s storage and execution strategy. section 6.3.1 section 6.11
A push iterator has the shape `func(yield func(V) bool)`. The producer calls `yield` for each value; its boolean result controls continuation. Returning `false` stops production early, so consumers can process all values, break out, or return without requiring the producer to first collect a complete slice. section 6.3.1 section 6.3.2
Figure 6.2 The Results iterator pushes values by calling the consumer’s yield.
The producer pushes each value by calling the consumer-provided `yield` function; the consumer’s return value determines whether iteration continues. section 6.3.1
Stream request results into a summary
`SendN` returns `Results`, an `iter.Seq[Result]`, rather than `[]Result`. It sends requests and yields each `Result`. `Summarize` consumes the iterator with an ordinary `for range`, accumulating request counts, errors, bytes, durations, and success rate. Because it accepts the iterator rather than a particular backing collection, the same summarizer can consume results originating from a slice or channel. section 6.3.2 section 6.3.3
Use the convention when an API benefits from incremental consumption:
- Avoid allocating and filling a complete result slice before a consumer can begin work. section 6.3.2
- Allow a consumer to stop once it has enough values. section 6.3.1 section 6.3.2
- Preserve a stable consumption API while changing internal work from sequential execution to a concurrent pipeline. section 6.3.1 section 6.3.2
- Guard iterator-consuming functions against nil when callers may pass one; ranging over a nil iterator panics. section 6.3.3 section 6.3.4














