I'm trying to create a VecDeque of structs that all implement an Animal
trait. This code works, but I don't understand why adding ' static
fixes it and how to make it use 'a
instead.
pub trait Animal {
fn says(self) -> Option<String>;
}
use std::collections::VecDeque;
pub struct Zoo {
list: VecDeque<Box<dyn Animal>>,
}
impl Zoo {
pub fn new() -> Zoo {
Zoo {
list: VecDeque::new(),
}
}
pub fn add<T>(&mut self, animal: T)
where
T: Animal + 'static,
{
self.list.push_back(Box::new(animal));
}
}
Two questions:
'a
properly and how this would work / what it would mean? And also I guess why I even need a lifetime here (is it because I'm using Box)?#[path="..."]
since without it, it asks me to move the file to src/lib/animal.rs
but when I move it, that still doesn't work.As already pointed out, Box<dyn Animal>
is equivalent to Box<dyn Animal + 'static>
, which means a pointer to something which is valid through the whole program (like string literals). This is probably not what you want.
You want it such that your Zoo
cannot live longer than your Animal
s. (This is what the compiler will enforce). So you annotate Zoo
with a lifetime 'a
and you require that every Animal
which is stored in the Zoo
lives at least as long as 'a
:
pub struct Zoo<'a> {
animals: VecDeque<Box<dyn Animal + 'a>>,
}
The compiler will check whether your lifetime annotations will make sense and enforce that a reference cannot outlive an object.