book icon indicating copy to clipboard operation
book copied to clipboard

Lifetimes as trait bounds

Open jgarvin opened this issue 4 years ago • 1 comments

I looked but was unable to find any explaining around constructs like this:

trait Foo : Display + 'static {
}

Or more commonly:

fn foo<T: Bar + 'static> {
}

That is, I haven't seen any discussion of lifetimes being "added" to traits. This was very confusing for a newbie.

Relatedly, I think new users are pretty likely to run into this as soon as they start trying to use the heap: https://users.rust-lang.org/t/box-with-a-trait-object-requires-static-lifetime/35261 Which requires understanding this. I think even going through that example specifically could be helpful.

jgarvin avatar Jul 12 '20 19:07 jgarvin

+1 I'm a noob and ran into this very quickly.

There are a few cases in the Book where '+static is added to a function parameter.

But there are currently no cases in the book where a named lifetime is added in return position, but this exactly what I needed.

I could try adding a section to this chapter: https://doc.rust-lang.org/stable/book/ch10-03-lifetime-syntax.html based on this example:

struct DivBy(u32);

impl DivBy {
    fn div_by(&self, n: u32) -> bool {
        self.0 % n == 0
    }
}

fn sample<'a>(n: &'a DivBy, sample_cnt: u32) -> impl Iterator<Item = bool> + 'a {
    (0..sample_cnt).map(|x| n.div_by(x))
}

Or this slightly longer example adapted from realish life, which also shows why one would need + 'static in parameter position, which is only touched on briefly elsewhere:

struct Funny(Box<dyn Fn(u32) -> bool>);

impl Funny {
    fn new<F>(f: F) -> Self
        where F: Fn(u32) -> bool + 'static
    {
        Self(Box::new(f))
    }
    fn at(&self, n: u32) -> bool {
        self.0(n)
    }
}

fn sample<'a>(f: &'a Funny, sample_cnt: u32) -> impl Iterator<Item = bool> + 'a {
    (0..sample_cnt).map(|x| f.at(x))
}

fn main() {
    let is_even = Funny::new(|x| x.rem_euclid(2) == 0);
    for val in sample(&is_even, 10) {
        println!("{}", val);
    }
}

mheiber avatar Dec 27 '21 13:12 mheiber