118. [T; N]::map — Transform an Array Without Allocating a Vec
[1, 2, 3].iter().map(|n| n * 2).collect::<Vec<_>>() works, but you’ve thrown the length away in the type and paid for a heap allocation. Arrays have their own map — same shape in, same shape out, no Vec in sight.
The reflex for transforming an array is the iterator chain:
| |
That gives you a Vec<i32>. The compiler no longer knows the length, and you allocated on the heap to find that out. If you want the array shape back, you’re stuck with try_into and a unwrap you don’t want.
[T; N]::map skips all of it. The output is [U; N] — same N, brand-new element type:
| |
No heap, no length erased, no try_into. Just an array on the stack with a different element type.
It takes each element by value, so it works fine with non-Copy types — no clone dance:
| |
The closure consumes the String, the array is moved, and you get a fresh [usize; 3] back. Compare to the iterator version, which would need .into_iter() plus a try_into to recover the array type.
It’s also a clean way to build initialized arrays from one you already have — RGB to RGBA, raw bytes to parsed records, anything fixed-width:
| |
When you genuinely want a Vec, .iter().map().collect() still wins. But when the length is part of the design — config slots, fixed-N pipelines, embedded buffers, no_std code — [T; N]::map keeps that fact in the type system instead of throwing it away.