Ownership in Rust
Ownership Rules
- Each value has a single owner
- Only one owner at a time
- When owner goes out of scope, value is dropped
fn main() {
{
let s = String::from("hello"); // s is valid here
// Operations with s
} // s is no longer valid - automatically dropped
}
Move Semantics
When you assign a variable to another variable, the ownership moves:
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 is moved to s2, s1 is no longer valid
// println!("{}", s1); // Error: value borrowed after move
println!("{}", s2); // Works fine
}
This also applies with function calls:
fn main() {
let s = String::from("hello");
takes_ownership(s); // s's value moves into the function
// s is no longer valid here
let x = 5;
makes_copy(x); // i32 datatype implements Copy trait, so x is still valid after
println!("{}", x); // Works fine
}
fn takes_ownership(some_string: String) {
println!("{}", some_string);
} // some_string goes out of scope and is dropped
fn makes_copy(some_integer: i32) {
println!("{}", some_integer);
} // some_integer goes out of scope, nothing special happens
Getting Ownership Back
Functions can also return ownership:
fn main() {
let s1 = gives_ownership(); // takes ownership from function
let s2 = String::from("hello"); // s2 comes into scope
let s3 = takes_and_gives_back(s2); // s2 is moved, s3 takes ownership
// s2 is no longer valid here, but s1 and s3 are
}
fn gives_ownership() -> String {
let s = String::from("hello");
s // returned and ownership moves to calling function
}
fn takes_and_gives_back(a_string: String) -> String {
a_string // returned and ownership moves to calling function
}
Clone and Copy Traits
Clone
Make a deep copy of heap data:
fn main() {
let s1 = String::from("hello");
let s2 = s1.clone(); // Deep copy, both s1 and s2 are valid
println!("s1 = {}, s2 = {}", s1, s2); // Works fine
}
Copy
Types with Copy trait are duplicated rather than moved:
fn main() {
let x = 5;
let y = x; // x is copied, not moved
println!("x = {}, y = {}", x, y); // Both valid
}
Types that implement Copy:
- All integer types (u32, i32, etc.)
- Boolean type (bool)
- Floating point types (f32, f64)
- Character type (char)
- Tuples that only contain Copy types, e.g., (i32, i32)