Check out a free preview of the full Rust for TypeScript Developers course

The "Borrow Checker Q&A" Lesson is part of the full, Rust for TypeScript Developers course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen answers questions about the borrow checker and scenarios around how long Rust keeps values in memory.


Transcript from the "Borrow Checker Q&A" Lesson

>> On a scale of one to dumb how does it make you feel?
>> I was confused about this example with respect to the previous examples of Rust being smart and knowing how long a thing lives.
>> So Rust, well I'd say it's better to do it this way.

There's the possibility of a safe program versus what Rust can identify as a safe program. Since it cannot guarantee that whatever, if let's pretend that this vector is freed right after this statement right here. Then we can't guarantee that that place in memory on the heap will exist.

So we cannot have references to it. So our little reference iterator fails. Let's just pretend it does live the whole time. That means Rust is doing things on your behalf. Rust doesn't do things on your behalf. You tell it how long it lives. So I'm telling it how long it should live for this statement.

So Rust just does exactly what you ask it to do at all points.
>> So do you release data then?
>> So normally you don't release data. You let Rust do it. Rust does it with the drop commit. You can technically, so if you get into async programming, you'll eventually create a semaphore.

Hey, what's a semaphore? A semaphore is just like a mutex with many roads if you will. And so you actually can on a permit. You can say, hey, I'm done using this semaphore and you can call it drop. Drop is a function, which does some freeing of values.

You can even implement your own version of drop if you want to be able to do different types of dropping or freeing of memory. That's, you're getting pretty fancy pants at that point, but you can get into it right there. So in general, I don't ever mess with that stuff.

I mean, I'm not even sure the use case of it other than this one semaphore situation we're actually manually called drop.
>> But most of the time drop is the one thing that rust does for us.
>> It;s the thing that Rust does for us now remember it all goes back to what's that?

Let's see, let me. Remember this thing that I was talking about. How every single thing, whoopsie-daisies. Every single thing that exists on the heap has a reference to the stack. So when the stack item, the vector, the number, the pointer, the length, and the capacity item goes out of scope.

It uses that to drop everything. And so that's why I talked about that is because if you think about it that way, once it's done on the stack, you lose it. And so in this case, it allocates it and drops it to look as it does its operations, drops it.

>> Is the reason that with our first and second example that holds out a bit longer is because those were atomic items that had like fixed length.
>> The reason why they held out longer is cause I did something like this. I did a catamorphic operation, right. [LAUGH] And so in other words what I'm doing is I'm doing a collect.

I'm taking it from referring to something inside of a vector to creating it into its own memory. So you can imagine I could do a sum here and now you don't need that anymore. You can just do that. So it's asking me what kind of sum are we?

Are we an i32? Sure we're an i32. I need to tell it what type of number it is. We could say it's whatever number you want, but there you go. We've told it and so now it created a temporary vector, created references to that vector mapped over each item referring inside the vector, and then sum them all up.

And so at some point, we've created new pieces of data. And this new pieces of the data is now right here.
>> Okay, so the first mute is a collect that stops after index zero.
>> Say that again?
>> So when we did with like our items list, first mute was like a collect that stopped after index zero.

It's like it did the first index. And it stopped.
>> Which one are we talking about right here? Are we talking about just so I understand just because I mean is it the one where I called first?
>> Yeah.
>> Here.
>> Yeah, this guy.
>> Get rid of 0, or sorry.

>> Yeah, I'm just gonna get rid of that. There we go.
>> So yeah, mine too. So, get mute zero is a collect call that stops after index 0.
>> No, what it is, is just literally referencing that individual item. So notice this thing holds onto the vector that vector lives for the entirety of this function.

So, these references are allowed to live for the duration of this function. That's why it works. So you couldn't do something like this, Right here. Right, you're gonna have some issues right here because now you're gonna have, let's see, or should have issues right here, println items. There we go.

We created the temporary vector for a second and then grabbed the first item out of it but then the vector's gone because no one holds onto the vector. So Rust just forces you to have your values last for the right duration. And then they can be removed. Does that make sense?

I mean, get mute zero is effectively the same thing as this, except for what comes out of it is not an immutable reference, but a mutable reference. And it's safe. It doesn't blow up if you access out of bounds

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