Ownership Basics
10 examples to get you started with ownership - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with ownership - 7 basic and 3 intermediate.
fn main() {
let s = String::from("owner");
consume(s);
// println!("{s}"); // error: moved
}
fn consume(s: String) {
println!("{s}");
}String owns heap bytess to consume moves ownershipconsume drops s at end of scopeRelated: Move Semantics & Copy -
Copytypes
Dropfn main() {
{
let s = String::from("temp");
println!("{s}");
} // drop runs here
println!("done");
}Drop::drop frees resources (heap for String)Related: Smart Pointers Basics - custom
Drop
fn main() {
let a = vec![1, 2, 3];
let b = a;
println!("{:?}", b);
}Vec is not Copyfn make_greeting() -> String {
String::from("hello")
}
fn main() {
let g = make_greeting();
println!("{g}");
}String when caller should own datastruct Pair { a: String, b: String }
fn main() {
let p = Pair { a: "x".into(), b: "y".into() };
let a = p.a; // partial move
// println!("{}", p.b); // OK
println!("{a}");
}Copyfn len(s: &String) -> usize { s.len() }
fn main() {
let s = String::from("rust");
println!("{}", len(&s));
println!("still own: {s}");
}&String borrows without taking ownership&mutRelated: Borrowing & References
Vec Growthfn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
let last = v.pop().unwrap();
println!("{last}, len={}", v.len());
}Vec owns a heap bufferpush may reallocate and move elementspop removes ownership of last element to callerVecDrop Side Effectsstruct LogOnDrop(&'static str);
impl Drop for LogOnDrop {
fn drop(&mut self) {
println!("dropping {}", self.0);
}
}
fn main() {
let _x = LogOnDrop("resource");
}Drop for cleanup beyond memorydrop called automatically, not recursively by valuestd::mem::drop(x) runs early drop explicitlyDrop::drop manually on valuesRc for Shared Ownership (Preview)use std::rc::Rc;
fn main() {
let a = Rc::new(String::from("shared"));
let b = Rc::clone(&a);
println!("refs={}", Rc::strong_count(&a));
drop(b);
println!("{a}");
}Rc counts owners in single-threaded codeRc::clone increments count, not deep clone of stringArc is the thread-safe variantRelated: Rc & Arc
fn main() {
let mut map = std::collections::HashMap::new();
map.insert("key".to_string(), vec![1, 2]);
if let Some(v) = map.remove("key") {
println!("{:?}", v);
}
}HashMap owns keys and valuesinsert moves value inremove moves value out (leaves absent key)get for read-only lookupRelated: Ownership Best Practices
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 19, 2026