Check out a free preview of the full The Rust Programming Language course

The "Lifetime Elision" Lesson is part of the full, The Rust Programming Language course featured in this preview video. Here's what you'd learn in this lesson:

Richard discusses that lifetime elision is when the compiler knows the lifetime of a variable and doesn't require annotations. Student questions regarding why the compiler cannot extend a variable's lifetime, why the function call in the example uses all_years and doesn't reference all_years, and what naming conventions are recommended for lifetime annotations are covered in this segment.


Transcript from the "Lifetime Elision" Lesson

>> Now, having said that, there's also this concept of lifetime illusion, which is basically saying, in some cases, the compiler knows what the lifetimes must be. And it doesn't actually require you to annotate them. So, I like to think of lifetime illusion as being somewhat similar to type inference in the sense that it's a way to say, I could write out the type here, but since the compiler knows exactly what the type is, anyway, I'm not gonna bother and it's going to be fine.

Similarly, sometimes you can say, I could write out the lifetime annotation here if I wanted to. In fact, if you want to anytime you have a reference anywhere in rust, you can put a lifetime annotation on it if you want to be explicit about it like that. But in practice a lot of the time, it's kind of a, more trouble than you necessarily want to take.

And so it's can be pretty nice that the rust compiler oftentimes will say, you know what, I know what the lifetime is here. You don't actually need to annotate this if you don't want to. So for example, here's how I could if I wanted to, I could have annotated our releases value here.

I could have said yes, this is a release a struct with a lifetime of tick a, if I wanted to, that's something I could do. It's not necessarily something that I want to do. And so if I wanted to I could use this right here like tick underscore, which is basically a way of saying, I don't actually care about what the lifetime of this thing is.

I know that there's some life time parameter there, but Russ compiler, you just figure it out take care of it and and I don't need to bother with it. And also it's why you can see things in various functions like that like length that we saw earlier that takes ampersand self.

You don't have to put ampersand tick a self for example. The rust compiler is smart enough to figure okay There's only one reference in this entire function type. Therefore, you don't need to bother giving it an annotation. I know that it's just like there's just the one lifetime.

You don't need to give it a name because the whole point of the name is to connect things. There's nothing to connect in a case like that. Actually, before we talk about the static lifetime limit, just pause and ask any questions about lifetime illusion or lifetime annotations in general?

>> Shouldn't the compiler know automatically if it deallocates the vector as it's being referenced by the slices?
>> Shouldn't the compiler know not to deallocate the vector because it's still being referenced by the slices, in other words. What if instead of giving you a compile error saying, hey, you need to fix something?

Why can't I just extend the lifetime and basically say, okay, well, there's still active references to this thing. So just don't deallocate it here and deallocate it sometime after the last reference expires. I'm assuming that is the question. That's how I understand it. It's a great question. I would say that the short answer here is that it's a design decision.

I have not personally thought through all the implications of what that might mean. I wouldn't be surprised if it turned out that if you had that as a policy, it created other edge cases that were even worse than getting a compiler error here but to be honest, I haven't really thought it through that much, but the short answer is that it is a design decision that the rust compiler makes.

And the policy is that slices and references are not allowed to outlive the thing that they're referencing. And what the compiler is policy is is just to give you an error when that happens. Is it possible that they could have gone a different way? I'm honestly not sure, I'm not enough of an expert on the compiler internals of the rust compiler to know that or even like, what design considerations are involved.

But suffice it to say that is the rule and that's what we got to work with. So the question is basically hey, why did we put these curly braces here that caused this problem? We could just get rid of the curly braces and then [LAUGH] we would not a lifetime issue the first place.

Yeah, absolutely correct. Short answer is I was trying to find an example that sort of minimally reproduce the problem. And before this, I had an even more involved example than this. And I was trying to sort of trim it down. And this was one of the ways that I decided to trim it down.

But yeah, I mean, you're absolutely right. In this case, we could get rid of that. As far as real world examples where this has come up, I have definitely personally run to this in a number of different situations. But they're all pretty complicated, the reasons lifetimes is at the very end of this course is because it really is kind of it has to do with the most well, not the most, but some of the most obscure edge cases that you can encounter having to do with the Baro checker.

And they solve problems related to that where basically you have complex relationships between references that are getting passed around and you want to model them explicitly, or maybe you even need to in order to disambiguate for the compiler, because it can't always allied them. But yeah, I wish I had off and a simple example I could rattle off but I couldn't come up with one.

Maybe somebody else can, but I couldn't think of one.
>> What are the kind of naming conventions you'd use for lifetimes, would you rather be more explicit rather than just take a do you wanna give it a name that means something?
>> That's a great question. Yeah, so the question was, wouldn't you rather use a more descriptive name than tick a like this is kind of your traditional single letter variable.

Honestly, a tick a itself is extremely common, it's probably the most common one you'll see in the wild by a lot. Because most often when you encounter something like this, it's like there's a function that has one maybe two lifetimes in it like differently named lifetimes. And so it's just sort of, I don't know, it's the one that's there.

So giving it a descriptive name isn't necessarily gonna help out much because there's just not that many that can possibly be confused cuz there's just so few of them and they also only exist generally speaking for the type signature or maybe inside the function in a couple of places.

Having said that, there is one library that I use that actually has three different type variables and it does use slightly more descriptive names for them, and they are pretty helpful. So, I'm not saying it doesn't happen, but it's pretty common to have single letter names for these things in practice, but you're absolutely free to use more helpful ones if you want and I definitely see that too.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now