I'd like to iterate over a collection, and during the iteration, have access to the value of the previous iteration. So I wanted to make an iterator that returned a pair of the current value and, if there is one, the previous value. Obviously if it returns the current value from next(), then that value will be consumed and can't be returned for the next loop, so the current value returned by next() has to be borrowed in some fashion. But I don't know exactly how to specify a borrowed value as the member of a struct. It says "missing lifetime specifier"
but the "Pair" struct can't take a lifetime, since that would mean the Iterator implementation would have to take a lifetime, and that errors out with "the lifetime parameter
'a is not constrained by the impl trait, self type, or predicates"
despite it being used by one of the predicates.
This is what I started with:
use std::env;
struct Pair where I: Iterator {
behind: Option,
current: &I::Item,
}
struct LookBehind where I: Iterator {
iter: I,
current: Option
}
impl Iterator for LookBehind {
type Item = Pair;
fn next(&mut self) -> Option> {
let behind = self.current;
self.current = self.iter.next();
match self.current {
Some(ref item) =>
match behind {
behind @ Some(_) => Pair {
behind: behind,
current: item
},
None => Pair {
behind: None,
current: item
}
},
None => None
}
}
}
fn lookbehind(iter: I) {
return LookBehind{iter: iter, current: None}
}
fn main() {
for pair in lookbehind(env::args().skip(1)) {
println!("{} {}",pair.behind,pair.current)
}
}
and this is when I specified the lifetime as required:
use std::env;
struct Pair<'a, I> where I: Iterator {
behind: Option,
current: &'a I::Item,
}
struct LookBehind where I: Iterator {
iter: I,
current: Option
}
impl<'a, I: Iterator> Iterator for LookBehind {
type Item = Pair<'a,I>;
fn next(&mut self) -> Option> {
let behind = self.current;
self.current = self.iter.next();
match self.current {
Some(ref item) =>
match behind {
behind @ Some(_) => Pair {
behind: behind,
current: item
},
None => Pair {
behind: None,
current: item
}
},
None => None
}
}
}
fn lookbehind(iter: I) {
return LookBehind{iter: iter, current: None}
}
fn main() {
for pair in lookbehind(env::args().skip(1)) {
println!("{} {}",pair.behind,pair.current)
}
}