macro_rules! rcomp {
(@__ $($vars:pat),+ in $iter:expr => $mapper:expr $(, if $guard:expr)? $(,)?) => { ... };
(@__ $($vars:pat),+ in $iter:expr, $($recurse:tt)+) => { ... };
(for $($t:tt)*) => { ... };
($collect:path; $($t:tt)*) => { ... };
}
Expand description
Generates an iterator that yields the results of the comprehension. The syntax allows for flattening, filtering, mapping, and collecting iterators (in that order).
There are 4 main components to a comprehension:
- The optional collection type, which is passed to a
collect
call by the macro. If this is omitted, the macro will return an iterator instead of a collection. - The
for-in
clause, which iterates over the input(s). This can be chained (e.g.for i in v1, j in v2, k in v3, ...
) to flatten nested iterators, up to the recursion limit. - The mapping expression, which transforms the input.
- The optional guard expression, which filters the input. Although this is
the last component of the comprehension, it is applied before the
mapping expression. In a sense, the end of the comprehension looks like
a
match
arm. This has a few implications which are explored more in the crate-level documentation.
With that explained, here’s the full syntax:
rcomp!([collect_ty;] for <pattern> in <iterator>, ... => <mapper>[, if <guard>]);
§Examples
Comprehensions can be as simple or complex as you want. They can collect
the input, filter it, map it, and flatten it all in one go. For example,
here’s how you can create a HashMap
of numbers and their squares using
a comprehension:
let m = rcomp![HashMap<_, _>; for i in 0..10 => (i, i * i)];
Another example is removing duplicates from a Vec
by converting it to
a HashSet
and back:
let v = vec![1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
let s = rcomp![Vec<_>; for i in rcomp![HashSet<_>; for j in &v => *j] => i];
See the crate-level documentation for more examples.