In this article, we explore Rust's borrowing rules, focusing on the interplay between mutable and immutable references. Learn why Rust's strict borrowing rules prevent simultaneous mutable and immutable references, ensuring memory safety and avoiding data races.
Welcome back, fellow Rustaceans 🦀
In our last article, we delved deeper into Rust's ownership model and its impact on how data is moved across a program. If you're coming from a C/C++ background, getting used to Rust's ownership model can take some time. We also explored how to retain variable ownership and avoid the unnecessary transfer of ownership through borrowing. Today, we'll dive further into the concept of borrowing and the rules that govern it.
Let's revisit an example from our previous article.
fn main() {
let s = String::from("Hello, Rust!");
borrow_ownership(&s);
println!("{}", s); // This works now
}
fn borrow_ownership(s: &String) {
println!("{}", s);
}
In this code, the borrow_ownership function takes a reference to the String variable s (&String). This allows borrow_ownership to use s without taking ownership, leaving the original s in main valid, so we can print it after the function call.
As we discussed, references in Rust are somewhat similar to pointers in C. You might wonder if using references reintroduces the same issues we had with pointers in C/C++, such as dangling pointers, wild pointers, and null pointer access. So, what's the point of learning Rust?
Although references in Rust are similar to pointers, Rust has an entire system built around references to prevent the pitfalls associated with pointers in C/C++. The borrow checker in the Rust compiler enforces strict rules to ensure memory safety. Any violation of these rules results in a compilation error. Let's examine these rules.
The Rules of Borrowing
Rust enforces strict borrowing rules to ensure memory safety:
At any given time, you can have either one mutable reference or any number of immutable references, but not both.
References must always be valid.
These rules prevent data races at compile time, ensuring safe and concurrent access to data. Let's look at each of these rules with examples.
Don't Miss an Update!
Helping you navigate the Embedded Systems career with ease! Technical posts, newsletters, special offers, and more.