Rust uses ownership to decide which value is responsible for freeing memory. When a value is moved, the original binding can no longer be used unless the type implements Copy. Borrowing lets you access data through references instead of taking ownership, while lifetimes describe how long those references remain valid. Together, these rules let Rust prevent dangling references and data races at compile time.
Master Rust Ownership and Borrowing
Learn move semantics, references, and lifetimes so you can write safe Rust code with confidence.
Start LearningUnderstand Rust’s Core Ownership Rules
Key Borrowing Patterns and Ownership Constraints
Shared References
Use shared references when multiple parts of your code only need to read the same data. Rust allows many immutable borrows at once, as long as no mutable borrow exists at the same time.
Mutable References
Use a mutable reference when one function or block needs to change a value in place. Rust permits only one mutable borrow at a time, which keeps updates exclusive and predictable.
Move Semantics
Many values are moved into a new variable, function, or collection rather than copied. After a move, the old owner is invalid, so functions must be designed to avoid using values after transfer.
Practical Lifetimes
Lifetimes tell Rust how borrowed values relate to each other in time. In real code, they often appear in function signatures that return references or accept multiple borrowed inputs.
Borrow Checker Fixes
Common errors happen when a value is used after move or when borrows overlap in incompatible ways. The usual fixes are to narrow scopes, pass references instead of values, or return owned data when borrowing is too restrictive.
Function Design
Structure functions around who owns the data and who only needs access. Choosing between taking ownership, borrowing immutably, or borrowing mutably makes APIs easier to use and keeps ownership rules clear.
Common Questions About Rust Borrowing
Why does the borrow checker reject valid-looking code?
Rust checks ownership and reference validity before the program runs. Code can look reasonable to a human but still allow a dangling reference or conflicting access, so the compiler blocks it early.
How do I fix a moved value error?
First, check whether the value should be borrowed instead of moved. If the function needs ownership, consider cloning only when duplication is truly appropriate, or restructure the code so the original value is no longer needed afterward.
When should I use a reference in a function?
Use a reference when a function only needs to inspect or temporarily modify data without taking it over. Use ownership when the function must store, return, or fully control that value.
How do lifetimes help with returning references?
Lifetimes show Rust which input data a returned reference depends on. They make sure the returned reference cannot outlive the data it points to.
What is the best way to satisfy ownership rules in practice?
Make borrows as short as possible, keep ownership clear in function signatures, and prefer passing references when ownership is not required. This usually removes conflicts without changing the program’s intent.