Open In App

Rust – References & Borrowing

As Rust Ownership rules say one owner at a time but there might some cases where we need to perform an action on data without affecting its original value. This is done via borrowing. Borrowing is like in general when we borrow something, and we are done with it, we give it back, but this doesn’t make us the owner of the data. Reference is an address that is passed to a function as an argument, and they always start with ampersand(&).

Rules of References

Let taken an example






fn main() {
    let gfg = String::from("geeksforgeeks");
    
    // gfg is passed as reference
    let length = calculate_length(&gfg); 
  
    // gfg goes out of scope
    println!("The length of '{}' is {}.", gfg, length);
  
fn calculate_length(gfg_len: &String) -> usize { 
    
    // gfg_len variable expecting string reference
    // returning length
    gfg_len.len() 
}

The variable gfg contains a string and is passed on to a function calculate_length as a reference which means gfg_len borrows the value of variable gfg to calculate its length, and it returns the borrowed at the end of the function. The function then returns the length of the passed reference string.

reference

Visual Representation of References:



visual representation

Now let us try to change the value of the borrowed program and see what we get




fn main() {
    let old = String::from("geeks");
    complete(&old);
}
fn complete(new: &String) { 
    new.push_str(", forgeeeks");
    println!("{}", new);
}

References and Mutability

Like variables in Rust, all references are mutable by default. Let us try to change the value we are referencing.




fn main() {
    let old = String::from("geeksforgeeks");
    change_reference(&old);
    println!("Old name = {}",old);
}
fn change_reference(new: &String) { 
    *new = String::from("GeeksForGeeks");
    println!("New name = {}", new);
}

This gives an error because values borrowed can’t be modified because we aren’t the owner of the value.

Mutable References

Rust supports mutable references which means we can change the value it references if it’s a mutable variable. There are some restrictions on how we use mutable references.

Let us change the program above to be valid




fn main() {
    let mut old = String::from("geeksforgeeks");
    println!("Old name = {}",old);
    change_reference(&mut old);
}
fn change_reference(new: &mut String) { 
    *new = String::from("GeeksForGeeks");
    println!("New name = {}", new);
}


Article Tags :