6
votes

I'd like to write some code like the following:

struct Foo {
    foo: usize
}

impl Foo {
    pub fn get_foo<'a>(&'a self) -> &'self usize {
        &self.foo
    }
}

But this doesn't work, failing with invalid lifetime name: 'self is no longer a special lifetime.

How can I return a reference that lives as long as the object itself?

2
My misunderstanding was that I thought it made sense to give out a lifetime that lives longer than the input lifetime. This doesn't make sense because if we have a borrow of self for 'a, then we can't borrow a field of self for longer than 'a. - yong

2 Answers

14
votes

You don't want the reference to live exactly as long as the object. You just want a borrow on the object (quite possibly shorter than the entire lifetime of the object), and you want the resulting reference to have the lifetime of that borrow. That's written like this:

pub fn get_foo<'a>(&'a self) -> &'a usize {
    &self.foo
}

Additionally, lifetime elision makes the signature prettier:

pub fn get_foo(&self) -> &usize {
    &self.foo
}
11
votes

In your example the lifetime of self is 'a so the lifetime of the returned reference should be 'a:

pub fn get_foo<'a>(&'a self) -> &'a usize {
    &self.foo
}

However the compiler is able to deduce (lifetime elision) the correct lifetime in simple cases like that, so you can avoid to specify lifetime at all, this way:

pub fn get_foo(&self) -> &usize {
    &self.foo
}

Look here for lifetime elision rules