196. Return impl Iterator, Not Vec — Let the Caller Decide What to Do
Returning a Vec from a helper allocates eagerly, every time — even when the caller only wants the first match or a running sum. Return impl Iterator instead and the allocation simply never happens unless the caller asks for it.
This is the function-boundary version of yesterday’s bite-195: chaining adapters avoids temporary Vecs inside a pipeline; returning impl Iterator avoids forcing one across a function call.
The eager version
A helper that builds and returns a Vec commits to a heap allocation and a full pass over the data before the caller has said what they want:
| |
If the caller just wants the first result, they still pay for the whole Vec:
| |
Hand back the iterator instead
Drop the .collect() and return the lazy iterator. The + '_ ties its lifetime to the borrowed slice:
| |
Now nothing runs until the caller pulls values through — and they pick the consumer:
| |
The find call never allocates and never touches the last element. The Vec-returning version couldn’t do that — collect() always drains the whole thing first.
The one rule: don’t borrow a local
The iterator you return can borrow your parameters, but not data you created inside the function — that data is dropped when the function ends. Iterators over owned values (like a Range) carry no borrow, so they just work:
| |
If you must produce owned data inside the function and stream it out, move it into the iterator (e.g. vec.into_iter() or a move closure) rather than returning a borrow of a local.