Understand Ownership and borrowing in Rust
Dsysd Dev
Posted on August 21, 2023
There are many tutorials available on this topic, here I try to show you how I understand this simple but very important concept
fn main() {
let mut num = 42;
// Immutable Borrow
let borrowed_immutable = #
println!("Immutable Borrow: {}", borrowed_immutable);
// Mutable Borrow
let borrowed_mutable = &mut num;
*borrowed_mutable += 10;
println!("Mutable Borrow: {}", borrowed_mutable);
// Cannot do an immutable borrow while there's a mutable borrow
// println!("Immutable Borrow: {}", borrowed_immutable);
}
The main function starts by creating a mutable variable num
with a value of 42
.
Immutable Borrowing:
An immutable borrow is created with let borrowed_immutable = #
. This means we're borrowing num in an immutable way, so we can read its value but not modify it.
We can have multiple such shared refereces.
Mutable Borrowing:
A mutable borrow is created with let borrowed_mutable = &mut num;
. This allows us to modify the value of num through the borrowed reference.
Since it's a mutable borrow, we use the *
operator to dereference the borrowed reference and modify the value. We add 10
to it.
The modified borrowed value is printed with println!
.
Trying to create an Immutable Borrow again
The code that attempts to create an immutable borrow after a mutable borrow is commented out.
Rust does not allow an immutable borrow while there's a mutable borrow. This is to prevent potential data races.
In Rust, mutable and immutable borrows have different rules to ensure memory safety.
When you have a mutable borrow, no other borrow (mutable or immutable) can be active at the same time.
This prevents data races where multiple parts of your code try to change data concurrently, which can lead to unpredictable behavior.
Understanding Ownership
fn main() {
let num: Box<i32> = Box::new(33);
ownership(num);
// println!("after owner: {}", num);
}
fn ownership(num: Box<i32>) {
println!("owned: {}", num);
let num2 = *num.as_ref() * 2;
println!("new num: {}", num2);
}
In the main function:
A variable named num
is created and assigned a Box
that contains the value 33
.
The Box
is a smart pointer created on heap that helps manage memory allocation and deallocation.
The ownership function is called, passing the num
Box to it.
There's a commented-out line that attempts to print the value of num after it's been passed to the ownership function.
However, this line is commented out because Rust's ownership system prevents using num after it's been moved to the ownership function.
The ownership function receives the ownership of the num
Box.
The value inside the Box
is printed using println!
.
The value is then multiplied by 2
and assigned to the variable num2
.
The new value, num2
, is printed using println!
.
The Key Concept
The key concept here is Rust's ownership system, which ensures memory safety and prevents certain types of bugs like null pointer dereferencing and data races.
In Rust, when a value is passed into a function (or moved to another variable), the ownership of that value is transferred.
This means the original variable can't be used afterward, to prevent issues like double freeing memory or using invalid references.
The Box type is used here to allocate memory on the heap for the i32
value (instead of the stack).
When the Box
is passed to the ownership function, ownership of the data moves to the function.
This concept is called "moving" in Rust.
This is the rust default as compared to CPP where values are copied.
Video Format
If you prefer video format, then have a look at this short
Conclusion
This code demonstrates Rust's strict ownership model and how it helps prevent memory-related bugs.
It might look a bit complicated at first, but Rust's ownership and borrowing rules play a significant role in ensuring the safety and reliability of your programs.
Claps Please!
If you found this article helpful I would appreciate some claps 👏👏👏👏, it motivates me to write more such useful articles in the future.
Follow for regular awesome content and insights.
Subscribe to my Youtube channel
Subscribe to my youtube channel if you are on the lookout for more such awesome content in video format.
Follow me on twitter 🐥
Join me on Twitter for a daily dose of knowledge, fascinating trivia, and valuable insights. Let's embark on a journey of continuous learning and discovery together! Follow me to stay inspired and informed. 🚀
Subscribe to my Newsletter
If you like my content, then consider subscribing to my free newsletter, to get exclusive, educational, technical, interesting and career related content directly delivered to your inbox
Important Links
Thanks for reading the post, be sure to follow the links below for even more awesome content in the future.
Twitter: https://twitter.com/dsysd_dev
Youtube: https://www.youtube.com/@dsysd-dev
Github: https://github.com/dsysd-dev
Medium: https://medium.com/@dsysd-dev
Email: dsysd.mail@gmail.com
Telegram 📚: https://t.me/dsysd_dev_channel
Linkedin: https://www.linkedin.com/in/dsysd-dev/
Newsletter: https://dsysd.beehiiv.com/subscribe
Gumroad: https://dsysd.gumroad.com/
Dev.to: https://dev.to/dsysd_dev/
Posted on August 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.