There is one thing that is easily overlooked: if you have a trait Bar
and you want to have a boxed trait object Box<dyn Bar>
, the compiler automatically adds a 'static
lifetime bound (as specified in RFC 599). This means that Box<dyn Bar>
and Box<dyn Bar + 'static>
are equivalent!
In your case, the compiler automatically adds the static bound such that this ...
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>>
... is equivalent to that:
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'static>
Now lifetime elision rules kick in and "connect" the two lifetime-slots, such that the above code is equivalent to:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'static>
But the type Iter<'a, Foo>
(the specific iterator type for Vec<Foo>
) obviously does not satisfy the bound 'static
(because it is borrowing the Vec<Foo>
)! So we have to tell the compiler that we don't want the default 'static
bound by specifying our own lifetime bound:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'a>
Now the compiler knows that the trait object is only valid for the lifetime 'a
. Note that we don't explicitly need to annotate the lifetime of the associated Item
type! Lifetime elision rules take care of that.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…