Rust - References & Borrowing
Last Updated :
18 Jul, 2021
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
- At any given time, you can have either one mutable reference or any number of immutable references.
- References must always be valid.
Let taken an example
Rust
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
Rust
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.
Rust
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.
- You can have only one mutable reference to a particular value in a particular scope to prevent data races
- If the immutable reference exists in our program then We can't have a mutable reference into the same value.
- You can have multiple immutable references in a particular scope because we can't change the value it references to
Let us change the program above to be valid
Rust
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);
}
Similar Reads
Rust - Reference Counted Smart Pointer In Rust, there is a concept of a Smart pointer where we use multiple ownership explicitly using the Rc<T> type. This Rc <type> is referred to as Reference counting. This concept was introduced in Rust to handle scenarios where a single value of the variable has multiple owners. Rc<T
2 min read
Reference String in Operating System When you go through topics like Page Replacement Algorithms you might have noticed that What is Reference String? In this article, we are going to discuss the topic Reference String in Operating Systems-Definition, Uses, Example with explanation, FAQs. What is Reference String in OS?Reference string
3 min read
Rust - Recoverable Errors An error is basically an unexpected behavior or event that may lead a program to produce undesired output or terminate abruptly. Errors are things that no one wants in their program. Recoverable errors are those that do not cause the program to terminate abruptly. Example- When we try to fetch a fil
4 min read
Rust - Generics Generics in Rust is a method of generalizing data types. Generics are always defined at run time. As generics can have multiple forms over given parameters and can be applied to methods, functions, structures, traits, etc they are often referred to as parametric polymorphism in type theory. Generics
2 min read
Rust - Dependencies In Rust, Â there are situations where we encounter situations where there is a dependency on other libraries. The rust ecosystem has a solution to it by having Cargo as its package manager that eases managing dependencies in almost all situations efficiently. Syntax:For creating a new library, we use
2 min read
Rust Types and Inference Pre-requisites: Rust, Scalar Datatypes in Rust Rust is a multi-paradigm programming language like C++ syntax that was designed for performance and safety, especially safe concurrency by using a borrow checker and ownership to validate references. In this article, we will focus on Rust's primitive t
12 min read