I want make the mapping portion of this line into a function:
let i: Vec<u32> = (0..=5).map(|x| x * 2).collect();
I wrote this code which I assumed would be a drop-in for what I removed from the original code:
let j: Vec<u32> = process(0..=5).collect();
fn process<I>(src: I) -> I
where
I: Iterator<Item = u32>,
{
src.map(|x| x * 2)
}
I get this compile time error:
error[E0308]: mismatched types
--> src/lib.rs:5:5
|
1 | fn process<I>(src: I) -> I
| - - expected `I` because of return type
| |
| this type parameter
...
5 | src.map(|x| x * 2)
| ^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `std::iter::Map`
|
= note: expected type parameter `I`
found struct `std::iter::Map<I, [closure@src/lib.rs:5:13: 5:22]>`
Since std::iter::Map<u32, u32> implements the Iterator trait, shouldn't it be able to be returned as Iterator<Item = u32>?
I was able to get it working with the following:
fn process<I>(src: I) -> std::iter::Map<I, Box<dyn Fn(u32) -> u32>>
where
I: Iterator<Item = u32>,
{
src.map(Box::new(|x| x * 2))
}
This involves wrapping the closure in a Box. Is there a better or less verbose way to do this that matches the inline function?