Edit: Lots of good solutions are downthread, but the software only lets me select one:
I'm trying to write some newtypes that change the iteration behavior of the values they're wrapping. Normally, I'd lean on the adapters provided by Iterator
to do this efficiently, but the use of closures makes their return types unnameable.
NB: In practice, the closure passed to the adapter will probably dispatch to a different closure stored inside the wrapper struct, so entirely eliminating closures isn't a viable path.
What's the best practice for dealing with this sort of situation? Do I need to hand-write the iterator with a bespoke next()
implementation?
struct Evens(Vec<u32>);
impl IntoIterator for Evens {
type Item=u32;
type IntoIter=std::iter::Filter<<Vec<u32> as IntoIterator>::IntoIter, _>;
fn into_iter(self)->Self::IntoIter {
let f = self.1;
self.0.into_iter().filter(|x| *x % 2 == 0)
}
}
fn main() {
for x in Evens(vec![1,2,3,4,5,6,7,8,9,10]) {
println!("{:?}", x);
}
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> src/main.rs:5:75
|
5 | type IntoIter=std::iter::Filter<<Vec<u32> as IntoIterator>::IntoIter, _>;
| ^ not allowed in type signatures
error: aborting due to previous error
For more information about this error, try `rustc --explain E0121`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.