138. iter::zip — Parallel Iteration Without the Method-Chain Dance
a.iter().zip(b.iter()) makes one collection the star and the other an awkward sidekick. std::iter::zip puts them on equal footing — two arguments, same indent, no method-chain twist.
The Problem
You have two collections that line up element-for-element. Pair them and walk through together:
| |
Functionally fine — but names is the subject of the chain while ages is shoved into an argument slot. When both collections are equally important to the loop, the asymmetry hides intent. Worse, swap one side for an owned value and the call site gets uglier: names.iter().zip(ages.into_iter()).
The Free Function
std::iter::zip is the same combinator, only as a free function. Both iterables sit at the same level:
| |
Both arguments are IntoIterator, so you can pass owned values, slices, or references directly — no per-side .iter() decoration to keep balanced.
Mixing Owned and Borrowed
The asymmetry of the method form shows up most when one side is owned:
| |
Same IntoIterator rules as a for loop: arrays by value yield items by value, references yield references.
Same Semantics as Iterator::zip
iter::zip(a, b) is exactly a.into_iter().zip(b). It stops at the shorter side and yields (A, B) tuples — no surprises:
| |
When to Reach for It
Use iter::zip when both sides are equal citizens of the loop — typical of parallel data, column-by-column processing, or test setup where inputs and expected outputs travel together. Stick with the method form when you’re already deep in an iterator chain and zipping is just one more step. Stable since Rust 1.59.