Ownership
Ownership is Rust's most unique feature and is key to its memory safety guarantees. There are three main rules: each value has a single owner, there can only be one owner at a time, and the value is dropped when the owner goes out of scope. This means Rust doesn't need a garbage collector.
When you assign one variable to another, Rust uses move semantics. This means the ownership transfers from the original variable to the new one. After the move, the original variable is no longer valid. If you want to keep both, you can use the clone method to make a deep copy.
Some types implement the Copy trait, which allows them to be copied instead of moved. These are typically simple types that live entirely on the stack. When you pass values to functions, ownership transfers to the function parameters. Similarly, returning values from functions transfers ownership back to the caller.
fn main() {
// Ownership rules
let s1 = String::from("hello");
let s2 = s1; // s1 is moved to s2
// println!("{}", s1); // This would cause an error
println!("s2: {}", s2);
// Clone for deep copy
let s3 = String::from("world");
let s4 = s3.clone();
println!("s3: {}, s4: {}", s3, s4); // Both are valid
// Copy trait - stack-only types
let x = 5;
let y = x; // x is copied, not moved
println!("x: {}, y: {}", x, y); // Both are valid
// Ownership transfer with functions
let name = String::from("Alice");
greet(name); // name is moved here
// println!("{}", name); // This would cause an error
// Ownership returned from function
let age = get_age();
println!("Age: {}", age);
}
fn greet(name: String) {
println!("Hello, {}!", name);
} // name is dropped here
fn get_age() -> i32 {
25 // Ownership returned to caller
}
Try it Yourself ->