|
|
| export const BLOG_POST_MD = String.raw`
|
| # Understanding Rust's Ownership System
|
|
|
| *Published on March 15, 2024 β’ 8 min read*
|
|
|
| Rust's ownership system is one of its most distinctive features, enabling memory safety without garbage collection. In this post, we'll explore how ownership works and why it's revolutionary for systems programming.
|
|
|
| ## What is Ownership?
|
|
|
| Ownership is a set of rules that governs how Rust manages memory. These rules are checked at compile time, ensuring memory safety without runtime overhead.
|
|
|
| ### The Three Rules of Ownership
|
|
|
| 1. **Each value has a single owner**
|
| 2. **There can only be one owner at a time**
|
| 3. **When the owner goes out of scope, the value is dropped**
|
|
|
| ## Memory Management Without GC
|
|
|
| Traditional approaches to memory management:
|
|
|
| - **Manual management** (C/C++): Error-prone, leads to bugs
|
| - **Garbage collection** (Java, Python): Runtime overhead
|
| - **Ownership** (Rust): Compile-time safety, zero runtime cost
|
|
|
| ## Basic Examples
|
|
|
| ### Variable Scope
|
|
|
| ${'```'}rust
|
| fn main() {
|
| let s = String::from("hello"); // s comes into scope
|
|
|
| // s is valid here
|
| println!("{}", s);
|
|
|
| } // s goes out of scope and is dropped
|
| ${'```'}
|
|
|
| ### Move Semantics
|
|
|
| ${'```'}rust
|
| fn main() {
|
| let s1 = String::from("hello");
|
| let s2 = s1; // s1 is moved to s2
|
|
|
| // println!("{}", s1); // β ERROR: s1 is no longer valid
|
| println!("{}", s2); // β
OK: s2 owns the string
|
| }
|
| ${'```'}
|
|
|
| ## Borrowing and References
|
|
|
| Instead of transferring ownership, you can **borrow** values:
|
|
|
| ### Immutable References
|
|
|
| ${'```'}rust
|
| fn calculate_length(s: &String) -> usize {
|
| s.len() // s is a reference, doesn't own the String
|
| }
|
|
|
| fn main() {
|
| let s1 = String::from("hello");
|
| let len = calculate_length(&s1); // Borrow s1
|
| println!("Length of '{}' is {}", s1, len); // s1 still valid
|
| }
|
| ${'```'}
|
|
|
| ### Mutable References
|
|
|
| ${'```'}rust
|
| fn main() {
|
| let mut s = String::from("hello");
|
|
|
| let r1 = &mut s;
|
| r1.push_str(", world");
|
| println!("{}", r1);
|
|
|
| // let r2 = &mut s; // β ERROR: cannot borrow twice
|
| }
|
| ${'```'}
|
|
|
| ## Common Pitfalls
|
|
|
| ### Dangling References
|
|
|
| ${'```'}rust
|
| fn dangle() -> &String { // β ERROR: missing lifetime specifier
|
| let s = String::from("hello");
|
| &s // s will be dropped, leaving a dangling reference
|
| }
|
| ${'```'}
|
|
|
| ### β
Solution
|
|
|
| ${'```'}rust
|
| fn no_dangle() -> String {
|
| let s = String::from("hello");
|
| s // Ownership is moved out
|
| }
|
| ${'```'}
|
|
|
| ## Benefits
|
|
|
| - β
**No null pointer dereferences**
|
| - β
**No data races**
|
| - β
**No use-after-free**
|
| - β
**No memory leaks**
|
|
|
| ## Conclusion
|
|
|
| Rust's ownership system eliminates entire classes of bugs at compile time. While it has a learning curve, the benefits in safety and performance are worth it.
|
|
|
| ## Further Reading
|
|
|
| - [The Rust Book - Ownership](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html)
|
| - [Rust by Example - Ownership](https://doc.rust-lang.org/rust-by-example/scope/move.html)
|
| - [Rustlings Exercises](https://github.com/rust-lang/rustlings)
|
|
|
| ---
|
|
|
| *Questions? Reach out on [Twitter](https://twitter.com/rustlang) or join the [Rust Discord](https://discord.gg/rust-lang)*
|
| `;
|
|
|