Rust for beginners — Part 7 — Borrowing reference, mutable borrow, immutable borrow
In the previous section we looked into how strings are used in rust, but we faced a scenario that when we assign a variable to another variable it gets permanently moved and the former variable cannot be used later.
So how do we handle this situation ?
Note: Kindly have a look into the previous section of tutorial to understand about Strings in rust
Previous section: https://medium.com/@manikandan96372/rust-for-beginners-part-6-string-71f15ab49505
fn main() {let a = String::from("hello");
let b = &a;println!("{}", a);
println!("{}", b);}
The above code snippet on execution would give the following output
hello
hello
In the above scenario how we are assigning variable “a” to variable “b” is not by moving the value of variable “a” to variable “b” instead variable “b” is borrowing the reference from variable “a” and it is achieved by using “&” symbol, When “&” symbol is put before a variable name then it refers to its address instead of the value itself.
Note: In this case we are not taking the address of the value of variable “a” from the memory heap and storing it in variable “b”, instead we are taking the address of variable “a” in the stack and storing that reference in variable “b”, so that variable “b” will point to variable “a” and variable “a” in turn points to value of variable “a” that is stored in memory heap
Mutable Borrow and Immutable Borrow
Now let’s try to push some value to variable “b”
fn main() {let a = String::from("hello");let b = &a;b.push_str(" world!");println!("{}", b);}
The above code snippet on execution would give the following error
The above error clearly states that variable “b” is been given the reference of variable “a” and it is not possible to mutate the value of variable “a” since variable “b” has not borrowed a mutable reference from variable “a”. This could be handled as follows
fn main() {let mut a = String::from("hello");let b = &mut a;b.push_str(" world!");println!("{}", b);println!("{}", a);}
The above code snippet on execution would give the following output
hello world!
hello world!
Works fine, now variable “b” has mutable reference of variable “a” by defining it as “&mut a”, which means it is passing the reference as a mutable one and the variable that uses this mutable reference has full access to modify it inside the code. But there are few restrictions to it when we borrow one variable in this fashion. To check that scenario let’s change the order of printing variable “a” and “b”
fn main() {let mut a = String::from("hello");let b = &mut a;b.push_str(" world!");println!("{}", a);println!("{}", b);}
The above code snippet on execution would give the following error
There is a restriction in rust that when you borrow a reference as a mutable one, the variable that has lend the reference is considered the immutable borrow (variable “a” in this case) and the variable that has taken the mutable reference is considered the mutable borrow (variable “b” in this case)
Immutable borrow should always be used in the code after the mutable borrow, because whatever modifications that are done by mutable borrow should not affect immutable borrow that’s why the right way is to always use immutable borrows after the mutable borrows.
Let’s consider the following code snippet
fn main() {let a = 10;
let b = &a;
let mut c = &b;c = 100;println!("{}", c);}
What we are trying to do here is, initially variable “a” is assigned a value of 10, variable “b” has the reference of variable “a”, and variable “c” is declared as a mutable variable and is assigned the reference of variable “b”, which means variable “c” is pointing to the address of variable “b” and in turn variable “b” is pointing to the address of variable “a”, where variable “c” now has a double reference ( first to variable “b” and second to variable “a” via variable “b”)
Then we are trying to re-assign a value to variable “c” as 100
The above code snippet on execution would give the following error
The above error states that since variable “c” has a double reference we cannot directly assign an integer to it, so how do we solve it ?
by re-assigning value to variable “c” with double ampersand (“&&”)
c = &&100
By this way we can handle double referencing scenario
Let’s look into &str in the next section