Rust Borrowing & Referencing Tutorial

In this Rust tutorial we learn how to borrow a value temporarily from its owner, which allows us to have multiple references to that value without breaking ownership.

We also learn about referencing the memory address of a value and how to get the value at that address with the dereferencing operator.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

Borrowing & Referencing

If we want to use a value in a function, without transferring ownership to the function, we can borrow the value temporarily from its owner. When the function is done with the value, it’s given back to the owner.

Borrowing allows us to have one or more references to a single value without breaking the “single owner” concept.

When we borrow a value, we reference its memory address with the & operator. A reference in Rust is an address that is passed to a function as an argument.

If you’re familiar with the C programming language, references would be similar to pointersOpens up in a new page .

How to reference and borrow a value from a variable

We use the & operator to reference a value’s memory address in Rust. Let’s see how this works with an example.

Example: reference and borrow a value from a variable
fn main() {

    let a = String::from("Hello");

    // reference a with &
    let str_len = get_str_length(&a);

    println!("String length: {}", str_len);

}

fn get_str_length(s:&String) -> usize {

    s.len()
}

In the example above, the variable a is the owner of the String “Hello”. If we use the variable in a function, it will pass ownership to the function. In this case we don’t want that, so the solution is to reference the owner (a) instead.

In the parameter list of the function definition, we add the & parameter before the type to tell Rust that the value coming in will be a reference to a value, not the actual value. The function only borrows the value, and gives it back after the function completes its execution.

When we call the function, we have to add the & operator again, this time in front of the value that we pass.

How to change a borrowed value

The borrowed value acts almost like a regular variable, it’s immutable. But, it can be made mutable with the mut keyword.

Example: mutate a borrowed value
fn main() {

    let mut a = 5;

    mutate_value(&mut a);

    println!("{}", a);

}

fn mutate_value(num:&mut i32) {

    *num = 3;
}

We have to add the mut keyword to the variable initialization, the function definition (in the parameter list) and the function call.

How to dereference a reference (retrieve its value)

When we use the reference ( & ) operator, we get the value’s memory address. To get the actual value at the address, we use the dereferencing operator ( * ).

Example: dereference a reference
fn main() {

    let mut a = 5;

    mutate_value(&mut a);

    println!("{}", a);

}

fn mutate_value(num:&mut i32) {

    // get the value at num's
    // address with * operator
    *num = 3;

}

In the function definition, we use the dereferencing operator to get the value at the memory address of the parameter and mutate it.

Summary: Points to remember

  • We can borrow a value temporarily from its owner without transferring ownership.
  • A reference is the memory address of a value and is passed to a function as an argument.
    • The reference operator is the & symbol.
  • We can find the value at the memory address with the dereferencing operator.
    • The dereference operator is the * symbol.
  • By default, a borrowed value is immutable but we can make it mutable with the mut keyword.