Why is adding life to a feature using the plus operator (Iterator <Item = & Foo> + a) necessary?
I apply a closure to an iterator and want to use a stable one, so I want to return a packed Iterator . The obvious way to do this is as follows:
struct Foo; fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>> { Box::new(myvec.iter()) } This did not help, because the borrowing supervisor cannot determine the appropriate life span.
After some research, I discovered how to return the iterator (or any other trait) correctly? , which led me to add + 'a :
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'a> { Box::new(myvec.iter()) } But I do not understand,
- What does it do
- Why is it needed here
There is one thing that is easy to overlook: if you have the Bar trait and want to have a boxed Box<dyn Bar> object, the compiler automatically adds a 'static lifetime (as specified in RFC 599 ). This means that Box<dyn Bar> and Box<dyn Bar + 'static> equivalent!
In your case, the compiler automatically adds a static border, so this is ...
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>> ... is equivalent to this:
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'static> Now the rules for choosing the lifetime are included and "connect" two intervals of the lifetime, so the above code is equivalent:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'static> But the type Iter<'a, Foo> (the specific type of iterator for Vec<Foo> ) obviously does not satisfy the 'static border (because it takes Vec<Foo> )! Thus, we must tell the compiler that we do not want the default binding of 'static , specifying our own lifetime limit:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'a> Now the compiler knows that the attribute object is valid only for the 'a lifetime. Note that we do not need to explicitly annotate the lifetime of the associated Item type! Lifetime selection rules take care of this.