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.