Rust Referenes and Borrowing


In Rust, references allow you to refer to a value without taking ownership of it. When you pass a reference to a value to a function, the function borrows the value, allowing it to use the value but not take ownership of it. This is called borrowing.

Here's an example:

fn print_string(s: &String) {
    println!("{}", s);

let s = String::from("hello");
print_string(&s); // pass a reference to s, ownership is not transferred

In this example, we're defining a function called print_string that takes a reference to a String value. We're then creating a new String value with the value "hello" and binding it to the variable s. Finally, we're calling the print_string function with a reference to s, which allows us to pass the value to the function without giving up ownership.

When you borrow a value in Rust, you can have multiple immutable references to the same value at the same time, but you can only have one mutable reference at a time. This ensures that multiple parts of your code can read a value at the same time, but only one part of your code can modify the value at a time.

Here's an example:

let mut s = String::from("hello");
let r1 = &s; // immutable borrow
let r2 = &s; // immutable borrow
let r3 = &mut s; // compile-time error: mutable borrow while immutable borrows exist

In this example, we're creating a new String value with the value "hello" and binding it to the variable s. We're then creating two immutable references to s using the variables r1 and r2. Finally, we're attempting to create a mutable reference to s using the variable r3, which results in a compile-time error since s is already borrowed immutably by r1 and r2.

By using references and borrowing, Rust ensures that your code is memory-safe and free from common issues such as null pointer dereferencing, use-after-free, and memory leaks.