Reputation: 766
Full Rust example here: https://play.rust-lang.org/?gist=0778e8d120dd5e5aa7019bc097be392b&version=stable
The general idea is to implement a generic split iterator that will yield iterators for each run of values that are split by the specified separator. So for [1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9],split(0)
you would get [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
For this code:
impl<'a, I, F> Iterator for Split<I, F>
where I: Iterator,
F: PartialEq<I::Item>,
{
type Item = SplitSection<'a, I, F>;
fn next(&'a mut self) -> Option<Self::Item> {
self.iter.peek().map(|_|
SplitSection {
exhausted: false,
iter: self,
})
}
}
I'm receiving the following error:
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:22:6
|
22 | impl<'a, I, F> Iterator for Split<I, F>
| ^^ unconstrained lifetime parameter
Is there a way to "constrain" the lifetime parameter, or refactor it somehow so that the associated type (Item) gets returned with a lifetime that will tie it back to next()?
Basically, since each SplitSection is using the iterator owned by Split, I want to make sure that two SplitSections are not iterated over at once.
Thanks!
Upvotes: 3
Views: 1738
Reputation: 3803
Sadly, this is currently not possible in Rust when implementing Iterator
trait - it is not allowed to modify lifetime relations compared to original trait definition of the method.
Good news are that recently merged generic associated type RFC will provide a language feature to do so, when implemented in the compiler. It will probably take some time though.
I have tried to implement similar function myself recently and most simple approach I have found with existing stable compiler was to require Clone + Iterator
, iterating split chunks separately from "host" iterator (https://gitlab.com/mihails.strasuns/example-iterators-calendar/blob/master/src/split_adaptor.rs)
Upvotes: 3