Reputation: 16425
I want to declare a member with type of Vector of trait in Rust but it is returning this error:
error: explicit lifetime bound required
This is what I have tried so far:
struct Lion {
legs: int,
}
trait Animal {
fn eat(&self);
}
impl Animal for Lion {
fn eat(&self) {
println!("Eat");
}
}
struct Zoo {
animals: Vec<Animal>,
}
I tried to search around the internet on how to fix this error with no luck. Can anyone give me a shed of light? Your help is much appreciated.
Upvotes: 0
Views: 1231
Reputation: 59005
Animal
is a trait, which means it could be implemented by just about anything. As such, you have to tell the compiler how long references contained by each thing that implements Animal
in the Vec
will be valid.
For example, you might have a Dodo
that contains short-lived lifetime; you wouldn't want it to go extinct whilst it's in your Vec
, leading to memory unsafety!
You need to use either
struct Zoo {
animals: Vec<Animal + 'static>,
}
or
struct Zoo<'a> {
animals: Vec<Animal + 'a>,
}
The first states that any reference reachable will be valid for the entire lifetime of the program. The second states that there is some lifetime 'a
for which all references reachable will be valid. The problem then, however, is that this code isn't valid anyway because...
error: the trait `core::kinds::Sized` is not implemented for the type `Animal+'static`
You cannot have a Vec
of values which are dynamically sized, which includes traits. You can solve this by either using Box<Animal + 'xxx>
, or &'xxx Animal + 'xxx
. A Box
will be a lot easier to manage.
Edit: To be accurate, any type which accepts a
Sized?
parameter works here. This boils down to any form of reference indirection.Rc
andArc
probably work, too.
FYI, that second form basically just says "a borrowed reference which is valid for all of lifetime 'xxx
(the &'xxx
part) to a value which implements Animal
, where any references said value contains are valid for at least the lifetime 'xxx
(the + 'xxx
part)."
Upvotes: 3