Transcript from the "The Static Lifetime & Lifetimes Recap" Lesson
>> So sack lifetime basically comes up when we assign things to string literals. So, throughout the course of these exercises we've been doing you may have seen something kind of surprising whenever we had like a vector of strings or something like that. Which is that it didn't have string with a capital S it had like ampersand STR like a string slice and you even wondering why.
[00:00:22] Well, that's because when I write this if I wanted to actually annotate this thing fully, this is what it would be. It's ampersand, tick static, stir equals, and then the string literal. So tick static is a special name. This is a reserved name. You're not allowed to name your stuff tick static.
[00:00:39] You can choose any name you want as long as it's not static. [LAUGH] When you're, when you're making a lifetime parameter, because static has a special 1 in the language. And tick static means this is the lifetime of the entire program. So things that have the static lifetime, they don't get allocated and they don't get deallocated, they just always exist.
[00:00:58] So you might be wondering like, okay, but like where like they're in memory somewhere, but like where are they in there? Memory and the answer is there in the binary itself, so when you have a string. This is a really common performance optimization like C does it rust does it like various other languages do it.
[00:01:14] When rust gets to this point in your code, it needs to know that the letters s a m are needs to know about those letters in order to put them somewhere. So one thing you could do is it could write them down in the binary SAM. And then when it gets to this line of code, it could say, okay, I'm gonna get heap allocation and copy the S over the A over the M over.
[00:01:32] But really, it's like, Y bother, it's already there in memory, like in the binary, the binary gets loaded into memory when you run it because that's where all the instructions are. So, like, why bother copying it over into the heap doing all that work when we can instead just like leave it where it is in the binary?
[00:01:47] And just say that this is going to be a reference directly to that memory inside the binary itself? Why not indeed. So that's exactly what it does. And the reason it's called the static lifetime is because the binary is like on your hard disk. And so, for the entire life of the program, that binary is going to be loaded into memory.
[00:02:03] So there's really no need to allocate or deallocate anything. It's also not going on the stack because, it operates more or less like a heap allocated thing. And that we will have submitted data structure that's going to have the index into the, what would ordinarily be heap memory.
[00:02:21] And basically this is just a way to say this lives forever, so titanic never gets allocated never needs to get deallocated, it just lives forever. And this is as efficient as it gets because there's no copying of any sort, there's no copying on the stack, there's no copying on the heap, it's just always there.
[00:02:39] So this is a these things are great for performance and that's exactly why when you make a string literal in rust, you, you get the static lifetime by default. But because of lifetime illusion, this is a very commonly alighted 1. And so usually the way I would actually write this is I would just say ampersand stir.
[00:02:56] And rust could just infer that like, okay, you don't need to put the lifetime there, I know that this is just a string reference. But now, thanks to our having talked about lifetimes, when you see this ,you know what is this a slice to what's actually it's not a slice of a string that was allocated on the heap, it's actually a slice of your binary itself.
[00:03:13] So [LAUGH] That was quite a moment when I learned that the first time honestly, this is the main layer, the main area where it comes up, you can also like make constants. And stuff using it but mainly the way that it comes up is just a Is for string literals.
[00:03:27] All right, so let's review our final section. First we talked about lifetime, so a lifetime is defined as the time between when a value is allocated. And when it's ultimately deallocated, that is that values lifetime. We talked about lifetime annotations, so here's a way to add a lifetime annotation to a struct.
[00:03:43] You can also add these to Neumes. In the case of rust, you do always need to add them to a struct if that struct contains any references. So I would not be allowed to say x has the type ampersand bracket I 64, I would need to see ampersand tick a I 64.
[00:04:00] And then I would need to have that tick a defined somewhere up here in full definition. We talked about lifetime illusion, so this is where in some cases I can omit the lifetime annotation because rust the rust compiler is capable of figuring it out. Much like with type inference if it can't figure it out don't worry, it'll give you a compile time error rather than just guessing.
[00:04:19] So it'll only elide these when it can successfully say like as an example of length, you can say okay, I can see that this only appears 1 time in here so you don't need to bother with it. You can just write ampersand self and not have to write ampersand tick a self.
[00:04:32] And finally, we talked about the static lifetime, which is basically a way of defining lifetimes that exists for the entire duration of the program. And the most common example of this is static. The ampersand tick static stir for string literals, which are stored in the actual application binary, as a very nice performance optimization to prevent needing to copy them onto the heap.