Reputation: 33
I'm learning Rust with the official book. I've come across a weird syntax in my program:
pub struct Shelf<'a> {
items: Vec<&'a Item<'a>>, // => working as expected
//items: Vec<Item<'a>>, // => not working
//items: Vec<&'a Item>, // => not working
}
Item is a struct that contains references to other types too:
pub struct Item<'a> {
owner: &'a Owner,
name: String,
avg_rating: u32,
status: ItemStatus,
}
pub struct Owner {
pub name: String,
}
It seems to me that the syntax items: Vec<&'a Item<'a>>
is weird and I don't think I'm doing right... What I want is a Vec
that contains references to Item
s, and that Vec
is valid as long as the references to Item
s it contains are themselves valid. Shouldn't it be items: Vec<&'a Item>
instead?
Upvotes: 3
Views: 6750
Reputation: 23264
There are two lifetimes that you need to specify:
You need to specify how long each type of reference lives. If you write Vec<&'a Item<'b>>
, the first lifetime ('a
) specifies how long references to items live, and the second lifetime ('b
) specifies how long the references to owners live.
When you write Vec<Item<'a>>
, the compiler doesn't know how long the items live.
When you write Vec<&'a Item>
, the compiler doesn't know how long the owners live.
When you use the same lifetime for both spots (Vec<&'a Item<'a>>
), you are telling the compiler that both lifetimes are the same, which means that items must live exactly as long as their owners. This may be overly restrictive, depending on your use case it might be better to tell the compiler that items may not live longer than their owners:
pub struct Shelf<'a, 'b: 'a> {
items: Vec<&'b Item<'a>>,
}
Upvotes: 9