Understanding Ownership and Borrowing Rules
Course Title: Mastering Rust: From Basics to Systems Programming Section Title: Ownership, Borrowing, and Lifetimes Topic: Understanding ownership and borrowing rules.
Introduction
In the previous topics, we covered the basics of Rust, including its history, goals, and use cases, as well as setting up the development environment and basic syntax. Now, we're going to dive into one of the most distinctive and powerful features of Rust: ownership and borrowing.
Ownership and borrowing are fundamental concepts in Rust that help prevent common programming errors such as null or dangling pointers. In this topic, we'll explore the rules of ownership and borrowing, and how they help ensure memory safety and prevent common errors.
What is Ownership?
In Rust, every value has an owner that is responsible for deallocating the value's memory when it is no longer needed. This is different from languages like C or C++, where memory is manually managed using pointers and explicit memory allocation and deallocation.
Here is an example of ownership in Rust:
let s = String::from("Hello, world!"); // s is the owner of the string "Hello, world!"
In this example, s
is the owner of the string "Hello, world!". When s
goes out of scope, the string "Hello, world!" will be deallocated.
Ownership Rules
There are three basic rules of ownership in Rust:
- Each value in Rust has an owner. This is the most basic rule of ownership. Every value in Rust has an owner that is responsible for deallocating the value's memory when it is no longer needed.
- There can be only one owner at a time. This rule ensures that there can only be one owner of a value at a time, which prevents multiple owners from trying to deallocate the same memory.
- When the owner goes out of scope, the value is dropped. This rule ensures that when the owner of a value goes out of scope, the value's memory is deallocated.
Here is an example that demonstrates these rules:
fn main() {
let s = String::from("Hello, world!"); // s is the owner of the string "Hello, world!"
println!("{}", s);
// When this function returns, the string "Hello, world!" is deallocated.
}
Borrowing
Borrowing is a way to let other parts of the code use a value without taking ownership of it. When you borrow a value, you are essentially creating a reference to it.
There are two types of borrowing in Rust:
- Immutable borrowing: This type of borrowing allows the borrower to read the value but not modify it.
- Mutable borrowing: This type of borrowing allows the borrower to read and modify the value.
Here is an example of borrowing in Rust:
fn main() {
let s = String::from("Hello, world!"); // s is the owner of the string "Hello, world!"
// Immutable borrowing
let len = calculate_length(&s); // We're borrowing s here
println!("The length of '{}' is {}.", s, len);
// Mutable borrowing
let mut s = String::from("Hello, world!"); // s is the owner of the string "Hello, world!"
change(&mut s);
println!("{}", s);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
fn change(some_string: &mut String) {
some_string.push_str(", world!");
}
Borrowing Rules
There are four basic rules of borrowing in Rust:
- You can have any number of immutable references to a value. You can have as many immutable references to a value as you want, and Rust will not prevent you from doing so.
- You can have only one mutable reference to a value. You can have only one mutable reference to a value at a time. This prevents multiple mutable references from trying to modify the same value.
- You cannot have an immutable reference to a value while you have a mutable reference to it. This ensures that you can't have an immutable reference to a value while you're trying to modify it through a mutable reference.
- You can't use a reference while the original value is mutably borrowed. This rule ensures that you can't use a reference to a value while the original value is mutably borrowed.
Conclusion
In this topic, we covered the fundamental concepts of ownership and borrowing in Rust. We learned about the ownership rules and how they help ensure memory safety and prevent common errors. We also learned about borrowing and the borrowing rules that ensure safe and efficient use of values.
Practical Takeaways
- Ownership and borrowing are fundamental concepts in Rust that help prevent common programming errors.
- You can have any number of immutable references to a value, but only one mutable reference.
- You cannot have an immutable reference to a value while you have a mutable reference to it.
- You can't use a reference while the original value is mutably borrowed.
Resources
What's Next?
In the next topic, we'll cover lifetimes and how they relate to ownership and borrowing.
Leave a comment below if you have any questions or need further clarification on ownership and borrowing rules!
Images

Comments