>> Welcome to the second video on borrowing in Rust.
When you borrow a variable,
you create a reference to that variable's value.
References, like variables, are immutable by default.
However, also like variables,
you can make a reference mutable as well.
Let's look at this in action.
Here, we create a vector with the elements 1, 2, and 3 in it,
and then we print the vector out.
Next, let's create a function that takes a mutable reference
to a vector of 32-bit integers and adds a value to that vector.
Back in the main function,
let's call add_to_vec and pass it a mutable reference to my_vec.
Notice that I need to specify that
the reference is mutable when I pass it.
Then let's print out the vec again.
When we run this code,
we see both the original vector
and the mutated vector printed out.
The add_to_vec function was able
to take a mutable reference to a vector,
then mutate the original vectors through that reference.
Like with ownership, there are rules for borrowing in Rust.
The first is, at any given time,
you can have either one mutable reference as we just saw
or any number of immutable references.
The second rule is that references must always be valid.
Let's look at an example of this second rule.
First, we create a String and assign it to the say variable.
Then we assign a reference to that String to the say2 variable.
Then let's print out both variables.
When we run this, we see the value of
both variables printing out just fine.
But what if we dropped the say variable before we print out say2?
When we run the code now,
we receive an error.
This is because when we dropped the say variable here,
it is no longer valid after this point
and we cannot access its value.
Additionally, any references to say's value,
like our say2 variable, also become invalid.
One way of referring to the time in which
a variable is valid is referring to that variable's lifetime,
say's lifetime starts when it is assigned a value,
and it ends when the value is dropped.
In order for this code to be valid,
say2's lifetime would need to still be in effect
when we attempt to print it out.
However, because it is a reference to the original say String,
its lifetime is tied to the original Strings lifetime.
As soon as we dropped the value of the first String,
any reference to that String's value
will be pointing to memory that no longer exists.
This code errors out because the last line attempts
to access a reference to a value in memory that no longer exists.
This is another way that Rust prevents dangling pointers.
When we compile a Rust program,
the Rust compiler runs through a phase called the borrow checker,
where it verifies that any values that are borrowed as references
are still valid when that references used.
Before we end, let's revisit the rules of borrowing.
At any given time for a given variable,
you can have either one mutable reference
or any number of immutable references
and references must always be valid.
Borrowing is a challenging concept.
This is partly because it is such a different way of managing
memory than what most programming languages do.
Once you understand how it works, however,
you also understand what it prevents you from doing
and how it makes sure that the code you write is memory safe.
I hope this video has helped you understand these concepts
and we will see you in the next one.
[MUSIC]