Industrial Training




Rust References & Borrowing

Reference is an address which is passed to a function as an argument. Borrowing is just like when we borrow something, and we are done with it, we give it back. References and Borrowing are mutual to each other, i.e. when a reference is released then the borrowing also ends.


Why Borrowing?


Borrowing concept is used because of the following reasons:


    Borrowing allows to have multiple references to a single resource but still obeys to have a "single owner".
    References are just like pointers in C.
    A reference is an object. References are of two types, i.e., mutable references and immutable references. Mutable references are moved while immutable references are copied.

Let's understand this through an example.
 fn main()  
{  
 let str=String::from("javaTpoint");  
 let len=calculate_length(&str);  
 println!("length of the string {}",len);  
}  
fn calculate_length(s:&String)->usize  
{  
  s.len()  
}  

Output:
length of the string 10

In the above example, calculate_length() function has a reference to string str as a parameter without taking its ownership.


let str=String::from("javaTpoint");  
et len=calculate_length(&str);  

In the above scenario, &str is a reference to variable str, but it does not own it. Therefore, the value pointed by the reference will not be dropped even when the reference goes out of scope.


fn calculate_length(s:&String)->usize  
  
 s.len()  

In the above case, variable 's' is valid until the control does not go back to the main() function. When the variables are passed as a reference to the function instead of actual values, then we don't need to return the values to give back the ownership.


Let's try to modify the borrowed value.
 fn main()  
{  
 let x=1;  
 value_changed(&x)  
}  
fn value_changed(y:&i32)  
{  
 *y=9;  
}  

Following is the output of the above program:

In the above example, it throws an error as &x is an immutable reference. Therefore, we cannot change the value of y.


Mutable Reference


We can fix the above error by using a mutable reference. Mutable references are those references which are changeable. Let's understand this through an example.


 fn main()  
{  
 let mut x=1;  
 value_changed(&mut x);  
 println!("After modifying, the value of x is {}",x);  
}  
fn value_changed(y:&mut i32)  
{  
 *y=9;  
}  

Output:
After modifying, the value of x is 9

In the above example, we create a mutable reference, i.e., &mut x and the reference is pointed by the variable y which is of &i32 type. Now, we can change the value which is referenced by 'y' variable. We assign 9 value i.e*y=9. Therefore, the value x also becomes 9 as the same memory location referenced by both the variables.


Restrictions of Mutable references


    We can have only one mutable reference to a piece of data in a particular scope.

For example:
 let mut str=String::from("javaTpoint");  
let a= &mut str;  
let b= &mut str;   

In the above scenario, the compiler throws an error as it consists of two mutable references which are not possible in Rust language.


    If the immutable reference exists in our program, then we cannot have a mutable reference in our program.

For example:
 let mut str=String::from("javaTpoint");  
let a= &str;  
let b=&str;  
let c=&mut str;

In the above scenario, the compiler throws an error because we cannot have a mutable reference while we have an immutable reference.




Hi I am Pluto.