I'd like to convert an iterator to a new iterator which yields every-other element, i.e. only the even indexed elements. Here's an attempt:
struct EvenIter<T, I: Iterator<Item = T>> {
inner: I
}
impl<I, T> Iterator<Item = T> for EvenIter<T, I> {
fn next(&mut self) -> Option<T> {
let temp = self.inner.next();
let _ = self.inner.next();
temp
}
}
pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> {
EvenIter { inner: iter }
}
The impl
line is wrong with error message
error[E0229]: associated type bindings are not allowed here
--> src/lib.rs:5:21
|
5 | impl<I, T> Iterator<Item = T> for EvenIter<T, I> {
| ^^^^^^^^ associated type not allowed here
Another attempt has exactly the same compiler error at exactly the same place:
struct EvenIter<T> {
inner: dyn Iterator<Item = T>
}
impl<T> Iterator<Item = T> for EvenIter<T> {
fn next(&mut self) -> Option<T> {
let temp = self.inner.next();
let _ = self.inner.next();
temp
}
}
pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> {
EvenIter { inner: iter }
}
How do we explain what we want to the compiler?
CodePudding user response:
The correct syntax for associated items is to put them inside the impl
block:
struct EvenIter<T, I: Iterator<Item = T>> {
inner: I
}
impl<I: Iterator<Item = T>, T> Iterator for EvenIter<T, I> {
type Item = T; // <-- here
fn next(&mut self) -> Option<T> {
let temp = self.inner.next();
let _ = self.inner.next();
temp
}
}
pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> {
EvenIter { inner: iter }
}
fn main() {
evens((0..10).into_iter()).for_each(|x| println!("{x}"));
}
Also, another constraint was required on I
in the impl, stating that I: Iterator<Item = T>
.