So here I wrote the iterator for generating permutations:
pub struct Permutations {
size: usize,
arr: Vec<usize>,
}
impl Permutations {
pub fn new(size: usize) -> Permutations {
Permutations{
size: size,
arr: (0..size).collect::<Vec<_>>(),
}
}
}
impl Iterator for Permutations {
type Item = Vec<usize>;
fn next(&mut self) -> Option<Self::Item> {
// some complex code here
if ok { Some(self.arr.clone()) } else { None }
}
}
Now, what I want is to not clone the vector each time, and return a constant reference. So I write:
impl Iterator for Permutations {
type Item = &Vec<usize>;
fn next(&mut self) -> Option<Self::Item> {
// some complex code here
if ok { Some(self.arr.clone()) } else { None }
}
}
And of course this does not compile, because I need to specify the lifetime. Ok, let's give it a try:
impl<'a> Iterator for Permutations {
type Item = &'a Vec<usize>;
fn next(&mut self) -> Option<Self::Item> {
// some complex code here
if ok { Some(&self.arr) } else { None }
}
}
Now I get an error:
error: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
So, I have no idea, what that means, but okay, I guess we need to bind that 'a lifetime to self somehow. After some poking around and fighting with hard-to-understand errors this came out:
use std::marker::PhantomData;
pub struct Permutations<'a> {
size: usize,
arr: Vec<usize>,
p: PhantomData<&'a Vec<usize>>,
}
impl<'a> Permutations<'a> {
pub fn new(size: usize) -> Permutations<'a> {
Permutations{
size: size,
arr: (0..size).collect::<Vec<_>>(),
p: PhantomData,
}
}
}
impl<'a> Iterator for Permutations<'a> {
type Item = &'a Vec<usize>;
fn next(&mut self) -> Option<Self::Item> {
// some complex code here
if ok { Some(&self.arr) } else { None }
}
}
But again there's an error, though kinda understandable one:
error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
return Some(&self.arr);
help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<Self::Item>
Okay! That is surprisingly actually useful! Let's add the explicit lifetime:
impl<'a> Iterator for Permutations<'a> {
type Item = &'a Vec<usize>;
fn next(&'a mut self) -> Option<Self::Item> {
// some complex code here
if ok { Some(&self.arr) } else { None }
}
}
Bam! Just as I thought: not useful at all.
error: method `next` has an incompatible type for trait: expected bound lifetime parameter , found concrete lifetime
Sooo... yeah. How do I do this simpliest thing in the world?