Lesson 9 of 50 · rust
Ownership Fundamentals
Duration: 15 minutes
Lesson 9 of 50 · rust
Duration: 15 minutes
rust\nfn main() {\n let s1 = String::from(\"hello\"); // s1 owns the String\n let s2 = s1; // Ownership moves to s2\n // println!(\"s1: {}\", s1); // ERROR! s1 no longer owns the data\n println!(\"s2: {}\", s2); // OK\n}\n\n\nWhen s2 = s1 executes, ownership transfers. s1 is no longer valid.\n\n## Stack vs Heap\n\nUnderstanding ownership requires knowing where data lives:\n\n### Stack\nFixed-size, fast, automatic cleanup. Stores simple types and references.\n\nrust\nlet x = 5; // Stack: integer\nlet y = x; // Stack: copies the value\nprintln!(\"x: {}, y: {}\", x, y); // Both valid (integers are Copy)\n\n\n### Heap\nVariable-size, allocated at runtime. Stores complex types.\n\nrust\nlet s = String::from(\"hello\"); // Data on heap, pointer on stack\n\n\n## Copy Types\n\nSimple types implement Copy, allowing implicit duplication:\n\nrust\nlet x = 5;\nlet y = x; // Copies the value (not move)\nprintln!(\"x: {}, y: {}\", x, y); // Both valid\n\n\nTypes that implement Copy: integers, floats, booleans, chars (and tuples of these).\n\n## Functions and Ownership\n\nPassing values to functions also transfers ownership:\n\nrust\nfn takes_ownership(s: String) {\n println!(\"{}\", s);\n} // s goes out of scope, String is dropped\n\nfn main() {\n let s = String::from(\"hello\");\n takes_ownership(s); // Ownership transferred\n // println!(\"s: {}\", s); // ERROR!\n}\n\n\n## Return Ownership\n\nFunctions can return ownership:\n\nrust\nfn return_string() -> String {\n String::from(\"hello\")\n}\n\nfn main() {\n let s = return_string(); // Ownership transferred to s\n println!(\"s: {}\", s); // OK\n}\n\n\n## Practical Example\n\nrust\nfn get_length(s: String) -> (String, usize) {\n let len = s.len();\n (s, len) // Return both String and its length\n}\n\nfn main() {\n let s = String::from(\"hello\");\n let (s, len) = get_length(s); // Reclaim ownership\n println!(\"The string '{}' has length {}\", s, len);\n}\n\n\nThis pattern is tedious—that's where borrowing comes in (next lesson).\n\n## Memory Safety Benefits\n\nOwnership prevents:\n- Use-after-free: Can't use freed memory\n- Double-free: Each value has one owner\n- Data races: Clear responsibility for cleanup\n\nThe compiler enforces all of this at compile time, with zero runtime cost.