Skip to content

Instantly share code, notes, and snippets.

@XMPPwocky
Last active August 29, 2015 14:16
Show Gist options
  • Save XMPPwocky/d820f45ac138bb4d6c3f to your computer and use it in GitHub Desktop.
Save XMPPwocky/d820f45ac138bb4d6c3f to your computer and use it in GitHub Desktop.

so you got some structs, right?

struct Foo<'a> {
    x: &'a String
}
struct Bar<'b> {
    y: &'b String
}   

and you try to do a thing....

let meow = String::new();
let woof = Foo {
    x: &meow
}

let's annotate all the variables with lifetimes.

'q: {
  let meow = String::new();
  'r: {
  let woof = Foo {
      x: &meow
  }
}

All references contain, as part of their type, a lifetime parameter. They use weird syntax for it- &'a T is really Reference<'a, T>. But nobody wants to type that out all the time.

What lifetime is used for the lifetime parameter when we write "&meow" ? The only reasonable answer is 'q ; it's the lifetime of meow, after all. If the lifetime that was used was any longer, you could access the contents of "meow" after it went out of scope! If it was any shorter, it would be too restrictive- you couldn't use the reference, even though "meow" is still in scope!

So- the lifetime inferred for the lifetime parameter of &x is the lifetime of x.

&'a T has an unusual restriction- if you should try to have an &'a T that itself has a lifetime longer than 'a, the compiler will complain, vigorously. This prevents dangling pointers- you cannot have a reference that outlives the thing it refers to.

Now, you might know that certain built-in traits like Copy have an unusual property; structs, enums, and tuples containing a non-Copy member are not Copy. This exact same thing happens with lifetimes!

For any lifetime- let's call it 'm- structs, enums, and tuples containing a member that cannot be allowed to live longer than 'm cannot, themselves, be allowed to live longer than 'm!

And consider the interaction of this with generics. If you have a struct

#[derive(Copy)]
struct Foo<T> {
    meow: T
}

that struct will only implement Copy if T does- whether Foo is Copy depends on T.

This happens with lifetimes too!

struct Foo<'a> {
    meow: &'a String
}

For any lifetime, whether Foo<'a> can be allowed to outlive that lifetime depends on whether its members can be allowed to outlive that lifetime. If the lifetime is longer than 'a, meow cannot be allowed to outlive that lifetime, and thus neither can Foo, because it contains meow!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment