Bird
Raised Fist0
Rustprogramming~20 mins

Ownership and scope in Rust - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Rust Ownership Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Understanding ownership transfer in Rust
What is the output of this Rust program?
Rust
fn main() {
    let s1 = String::from("hello");
    let s2 = s1;
    println!("{}", s2);
}
Ahellohello
BCompilation error: use of moved value 's1'
Chello
DRuntime error: null pointer dereference
Attempts:
2 left
💡 Hint
Remember that in Rust, assigning a String moves ownership, so s1 is no longer valid after the move.
❓ Predict Output
intermediate
2:00remaining
Borrowing and scope lifetime
What will this Rust code print?
Rust
fn main() {
    let s = String::from("world");
    {
        let r = &s;
        println!("{}", r);
    }
    println!("{}", s);
}
A
world
world
B
world
Compilation error: cannot use s while borrowed
CCompilation error: r does not live long enough
DRuntime error: use after free
Attempts:
2 left
💡 Hint
The reference r is valid only inside the inner block, but s is still valid after.
❓ Predict Output
advanced
2:00remaining
Mutable borrow and scope rules
What error or output does this Rust code produce?
Rust
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s;
    println!("{} and {}", r1, r2);
}
ACompilation error: cannot borrow 's' as mutable more than once at a time
Bhello and hello
Chello and Compilation error: use of moved value
DRuntime error: data race detected
Attempts:
2 left
💡 Hint
Rust allows only one mutable reference at a time to prevent data races.
❓ Predict Output
advanced
2:00remaining
Dangling reference prevention
What happens when you run this Rust code?
Rust
fn dangle() -> &String {
    let s = String::from("hello");
    &s
}

fn main() {
    let reference = dangle();
    println!("{}", reference);
}
ACompilation error: missing lifetime specifier
Bhello
CRuntime error: use after free
DCompilation error: returns reference to local variable
Attempts:
2 left
💡 Hint
Rust prevents returning references to data that will be dropped.
🧠 Conceptual
expert
3:00remaining
Ownership and borrowing combined scenario
Consider this Rust code snippet. What is the value of 'count' after execution?
Rust
fn main() {
    let mut count = 0;
    let mut s = String::from("hello");
    {
        let r1 = &s;
        let r2 = &s;
        count += r1.len() + r2.len();
    }
    let r3 = &mut s;
    r3.push_str(" world");
    count += r3.len();
    println!("{}", count);
}
ARuntime error: data race
B21
CCompilation error: cannot borrow 's' as mutable because it is also borrowed as immutable
D11
Attempts:
2 left
💡 Hint
Immutable borrows end before mutable borrow starts, so all operations are valid.

Practice

(1/5)
1. What does ownership in Rust primarily ensure?
easy
A. Ownership is not related to variable scope
B. Multiple variables can own the same value simultaneously
C. Variables can share ownership without restrictions
D. Only one variable owns a value at a time

Solution

  1. Step 1: Understand ownership concept

    Ownership means a value has exactly one owner variable at any time.
  2. Step 2: Compare options with ownership rule

    Only one variable owns a value at a time states single ownership, others allow multiple owners or unrelated concepts.
  3. Final Answer:

    Only one variable owns a value at a time -> Option D
  4. Quick Check:

    Ownership = single owner [OK]
Hint: Ownership means one owner per value, no sharing [OK]
Common Mistakes:
  • Thinking multiple variables can own the same value
  • Confusing ownership with borrowing
  • Ignoring the role of scope in ownership
2. Which of the following is the correct way to declare a variable with ownership in Rust?
easy
A. let x = String::from("hello");
B. var x = "hello";
C. int x = 5;
D. let x := "hello";

Solution

  1. Step 1: Identify Rust variable declaration syntax

    Rust uses 'let' keyword and type inference or explicit types.
  2. Step 2: Check each option for Rust syntax

    let x = String::from("hello"); uses 'let' and String::from correctly; others use invalid syntax for Rust.
  3. Final Answer:

    let x = String::from("hello"); -> Option A
  4. Quick Check:

    Rust variables start with let [OK]
Hint: Rust variables start with 'let' keyword [OK]
Common Mistakes:
  • Using 'var' instead of 'let'
  • Using ':=' which is not Rust syntax
  • Declaring types like 'int' which is not Rust
3. What will be the output of this Rust code?
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1);
medium
A. hello
B. Runtime error
C. Compile-time error
D. hellohello

Solution

  1. Step 1: Understand ownership move in assignment

    Assigning s1 to s2 moves ownership; s1 is no longer valid.
  2. Step 2: Check usage of s1 after move

    Using s1 in println! after move causes compile-time error due to invalid ownership.
  3. Final Answer:

    Compile-time error -> Option C
  4. Quick Check:

    Using moved value = compile error [OK]
Hint: Using moved variable causes compile error [OK]
Common Mistakes:
  • Assuming s1 still owns the value after move
  • Expecting runtime error instead of compile error
  • Thinking both s1 and s2 own the value
4. Identify the error in this Rust code snippet:
fn main() {
    let s = String::from("hello");
    takes_ownership(s);
    println!("{}", s);
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
}
medium
A. Using s after ownership moved to function
B. Missing semicolon after println!
C. Function takes_ownership should return String
D. String::from is invalid syntax

Solution

  1. Step 1: Analyze ownership transfer to function

    Passing s to takes_ownership moves ownership to function parameter.
  2. Step 2: Check usage of s after function call

    Using s in println! after move causes compile-time error because s is invalid.
  3. Final Answer:

    Using s after ownership moved to function -> Option A
  4. Quick Check:

    Use after move = error [OK]
Hint: Ownership moves into function, original variable invalid after [OK]
Common Mistakes:
  • Thinking function parameter borrows instead of takes ownership
  • Expecting runtime error instead of compile-time
  • Ignoring ownership rules with function calls
5. Given this Rust code, what is the correct way to allow main to use s after passing it to takes_ownership?
fn main() {
    let s = String::from("hello");
    takes_ownership(s);
    println!("{}", s);
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
}
hard
A. Return the String from takes_ownership and assign back in main
B. All of the above
C. Clone s before passing: takes_ownership(s.clone())
D. Change takes_ownership to borrow: fn takes_ownership(some_string: &String)

Solution

  1. Step 1: Understand ownership transfer problem

    Passing s moves ownership, so s is invalid after call.
  2. Step 2: Review options to keep s usable

    Change takes_ownership to borrow: fn takes_ownership(some_string: &String) borrows s, so ownership not moved. Return the String from takes_ownership and assign back in main returns ownership back. Clone s before passing: takes_ownership(s.clone()) clones s to keep original.
  3. Step 3: Confirm all options fix the problem

    All three approaches prevent use-after-move error, so all are correct.
  4. Final Answer:

    All of the above -> Option B
  5. Quick Check:

    Borrow, return, or clone fixes ownership [OK]
Hint: Borrow, return ownership, or clone to keep variable usable [OK]
Common Mistakes:
  • Thinking only borrowing works
  • Ignoring cloning as a solution
  • Not returning ownership from function
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