Bird
Raised Fist0
Rustprogramming~10 mins

Ownership rules in Rust - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Ownership rules
Create variable with data
↓
Variable owns data
↓
Move ownership?
Yes→Old variable invalid
↓
New variable owns data
↓
Use variable
↓
Variable goes out of scope
↓
Data dropped automatically
This flow shows how ownership starts with a variable, can move to another variable, and how data is dropped when the owner goes out of scope.
Execution Sample
Rust
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // ownership moves
    println!("{}", s2);
}
This code creates a string, moves ownership from s1 to s2, then prints s2.
Execution Table
StepActionVariable StatesOwnershipOutput/Note
1Create s1 with "hello"s1 = "hello", s2 = Nones1 owns dataNo output
2Move ownership s1 -> s2s1 = invalid, s2 = "hello"s2 owns dataNo output
3Print s2s2 = "hello"s2 owns dataOutput: hello
4End of main, s2 goes out of scopes2 droppedNo ownerData dropped automatically
💡 Execution stops after main ends and data is dropped.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
s1None"hello"invalid (moved)invalid (moved)invalid (moved)
s2NoneNone"hello""hello"dropped
Key Moments - 3 Insights
Why can't we use s1 after moving ownership to s2?
Because ownership moved to s2 at step 2, s1 becomes invalid and cannot be used, as shown in the execution_table row 2.
What happens to the data when the owner variable goes out of scope?
At step 4, when s2 goes out of scope, Rust automatically drops the data to free memory, as shown in the execution_table.
Does moving ownership copy the data?
No, ownership moves without copying data. The original variable becomes invalid, preventing double free errors.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the state of s1 after step 2?
As1 is invalid (moved)
Bs1 is copied
Cs1 still owns the data
Ds1 is dropped
💡 Hint
Check the 'Variable States' column in row 2 of the execution_table.
At which step does the program print the string "hello"?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look at the 'Output/Note' column in the execution_table.
If we tried to print s1 after step 2, what would happen?
AIt would print "hello"
BIt would cause a compile error
CIt would print nothing
DIt would print garbage data
💡 Hint
Ownership moved at step 2, making s1 invalid as shown in variable_tracker.
Concept Snapshot
Ownership rules in Rust:
- Each value has one owner variable.
- Ownership can move (transfer) but not copy by default.
- After move, old owner is invalid.
- When owner goes out of scope, data is dropped automatically.
- Prevents memory errors safely.
Full Transcript
This visual execution shows how Rust's ownership rules work. First, a variable s1 is created owning a string "hello". Then ownership moves from s1 to s2, making s1 invalid. We print s2 successfully. At the end, s2 goes out of scope and Rust automatically frees the data. This prevents bugs by ensuring only one owner exists at a time and data is cleaned up safely.

Practice

(1/5)
1. What happens when ownership of a variable is moved to another variable in Rust?
easy
A. The original variable becomes invalid and cannot be used.
B. Both variables can be used independently without restrictions.
C. The data is copied and both variables own separate copies.
D. The original variable automatically deletes the data.

Solution

  1. Step 1: Understand ownership move

    When ownership moves, the original variable loses its right to access the data.
  2. Step 2: Effect on original variable

    The original variable becomes invalid and cannot be used to prevent double free errors.
  3. Final Answer:

    The original variable becomes invalid and cannot be used. -> Option A
  4. Quick Check:

    Ownership move invalidates old owner = A [OK]
Hint: Ownership move disables old variable usage [OK]
Common Mistakes:
  • Thinking ownership move copies data
  • Assuming both variables remain valid
  • Confusing move with borrowing
2. Which of the following is the correct syntax to borrow a variable immutably in Rust?
easy
A. let ref x = value;
B. let x = value;
C. let x = *value;
D. let x = &value;

Solution

  1. Step 1: Identify borrowing syntax

    Immutable borrowing uses the & symbol before the variable.
  2. Step 2: Match correct syntax

    let x = &value; correctly borrows value immutably.
  3. Final Answer:

    let x = &value; -> Option D
  4. Quick Check:

    Immutable borrow uses & = B [OK]
Hint: Use & to borrow immutably [OK]
Common Mistakes:
  • Using * for borrowing instead of dereferencing
  • Missing & symbol for borrowing
  • Confusing mutable and immutable borrow syntax
3. What will be the output of this Rust code?
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1);
medium
A. Runtime error
B. hello
C. Compilation error
D. Empty string

Solution

  1. Step 1: Analyze ownership move

    Assigning s1 to s2 moves ownership, invalidating s1.
  2. Step 2: Using invalidated variable

    Printing s1 after move causes a compile-time error because s1 is no longer valid.
  3. Final Answer:

    Compilation error -> Option C
  4. Quick Check:

    Using moved variable causes compile error = A [OK]
Hint: Using moved variable causes compile error [OK]
Common Mistakes:
  • Expecting s1 to print after move
  • Confusing move with copy
  • Thinking runtime error occurs instead
4. Identify the error in this Rust code snippet:
let s = String::from("hello");
let r1 = &s;
let r2 = &mut s;
println!("{} and {}", r1, r2);
medium
A. No error, code runs fine.
B. Cannot borrow s as mutable because it is already borrowed as immutable.
C. String::from is not a valid function.
D. Cannot print two variables in one println! macro.

Solution

  1. Step 1: Check borrowing rules

    Rust forbids mutable borrow if immutable borrow exists simultaneously.
  2. Step 2: Identify conflict

    r1 is an immutable borrow; r2 tries mutable borrow causing error.
  3. Final Answer:

    Cannot borrow s as mutable because it is already borrowed as immutable. -> Option B
  4. Quick Check:

    Mutable borrow conflicts with existing immutable borrow = D [OK]
Hint: Mutable borrow disallowed if immutable borrow exists [OK]
Common Mistakes:
  • Ignoring borrow rules and expecting code to run
  • Thinking multiple mutable borrows allowed
  • Misunderstanding println! macro usage
5. Given this Rust function:
fn take_ownership(s: String) {
    println!("{}", s);
}

fn main() {
    let s = String::from("hello");
    take_ownership(s);
    println!("{}", s);
}
What is the correct way to fix the error without cloning the string?
hard
A. Change the function parameter to borrow the string: fn take_ownership(s: &String)
B. Remove the println! after the function call.
C. Declare s as mutable in main.
D. Use let s = &String::from("hello"); in main.

Solution

  1. Step 1: Understand ownership transfer

    Passing s to take_ownership moves ownership, invalidating s in main.
  2. Step 2: Use borrowing to avoid move

    Changing parameter to &String borrows s, so ownership stays with main.
  3. Step 3: Adjust function call

    Call take_ownership(&s) to pass reference matching new parameter.
  4. Final Answer:

    Change the function parameter to borrow the string: fn take_ownership(s: &String) -> Option A
  5. Quick Check:

    Borrow parameter to keep ownership in caller = C [OK]
Hint: Borrow in function parameter to keep ownership [OK]
Common Mistakes:
  • Trying to use s after move without borrowing
  • Removing code instead of fixing ownership
  • Confusing mutability with ownership
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard