Gilles
Gilles

Reputation: 33

Rust lifetime in Vec<&T> : convoluted syntax

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 Items, and that Vec is valid as long as the references to Items it contains are themselves valid. Shouldn't it be items: Vec<&'a Item> instead?

Upvotes: 3

Views: 6750

Answers (1)

Jmb
Jmb

Reputation: 23264

There are two lifetimes that you need to specify:

  • Your vector contains reference to items.
  • Each item contains a reference to its owner.

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

Related Questions