In real life applications, most of the times we have to pass variable bindings to other functions or assign them to other variable bindings. In this case, we are referencing the original binding; borrow the data of it.
Borrow (verb)
To receive something with the promise of returning it.
⭐️ There are two types of Borrowing,
-
Shared Borrowing
(&T)
- A piece of data can be borrowed by a single or multiple users, but data should not be altered.
-
Mutable Borrowing
(&mut T)
- A piece of data can be borrowed and altered by a single user, but the data should not be accessible for any other users at that time.
There are very important rules regarding borrowing,
-
One piece of data can be borrowed either as a shared borrow or as a mutable borrow at a given time. But not both at the same time.
-
Borrowing applies for both copy types and move types.
-
The concept of Liveness ↴
fn main() {
let mut a = vec![1, 2, 3];
let b = &mut a; // &mut borrow of `a` starts here
// ⁝
// some code // ⁝
// some code // ⁝
} // &mut borrow of `a` ends here
fn main() {
let mut a = vec![1, 2, 3];
let b = &mut a; // &mut borrow of `a` starts here
// some code
println!("{:?}", a); // trying to access `a` as a shared borrow, so giving an error
} // &mut borrow of `a` ends here
fn main() {
let mut a = vec![1, 2, 3];
{
let b = &mut a; // &mut borrow of `a` starts here
// any other code
} // &mut borrow of `a` ends here
println!("{:?}", a); // allow borrowing `a` as a shared borrow
}
💡 Let’s see how to use shared and mutable borrowings in examples.
fn main() {
let a = [1, 2, 3];
let b = &a;
println!("{:?} {}", a, b[0]); // [1, 2, 3] 1
}
fn main() {
let a = vec![1, 2, 3];
let b = get_first_element(&a);
println!("{:?} {}", a, b); // [1, 2, 3] 1
}
fn get_first_element(a: &Vec<i32>) -> i32 {
a[0]
}
fn main() {
let mut a = [1, 2, 3];
let b = &mut a;
b[0] = 4;
println!("{:?}", b); // [4, 2, 3]
}
fn main() {
let mut a = [1, 2, 3];
{
let b = &mut a;
b[0] = 4;
}
println!("{:?}", a); // [4, 2, 3]
}
fn main() {
let mut a = vec![1, 2, 3];
let b = change_and_get_first_element(&mut a);
println!("{:?} {}", a, b); // [4, 2, 3] 4
}
fn change_and_get_first_element(a: &mut Vec<i32>) -> i32 {
a[0] = 4;
a[0]
}