Bird
Raised Fist0
Rustprogramming~5 mins

Function ownership interaction in Rust - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What happens to ownership when a variable is passed to a function in Rust?
When a variable is passed to a function, ownership of the variable is moved to the function unless the variable implements the Copy trait or is passed by reference.
Click to reveal answer
beginner
How can you allow a function to use a variable without taking ownership in Rust?
You can pass a reference to the variable using the & symbol, so the function borrows the variable instead of taking ownership.
Click to reveal answer
intermediate
What is the difference between passing by value and passing by reference in Rust functions?
Passing by value moves ownership to the function, potentially invalidating the original variable. Passing by reference lets the function borrow the variable without taking ownership, so the original variable remains valid.
Click to reveal answer
intermediate
What happens if a function returns a value that it took ownership of?
The ownership of the returned value is transferred back to the caller, allowing the caller to use the value again.
Click to reveal answer
beginner
Why does Rust prevent use of a variable after its ownership has been moved to a function?
Rust enforces ownership rules to prevent bugs like use-after-free. Once ownership is moved, the original variable is invalidated to ensure memory safety.
Click to reveal answer
What keyword allows a function to borrow a variable without taking ownership in Rust?
Amut
B*
C&
Dref
If a function takes ownership of a String, what happens to the original variable after the function call?
AIt is borrowed mutably.
BIt becomes invalid and cannot be used.
CIt is copied automatically.
DIt remains valid and unchanged.
How can a function return ownership of a value back to the caller?
ABy using the Copy trait.
BBy passing a reference.
CBy cloning the value.
DBy returning the value from the function.
Which of these types is copied rather than moved when passed to a function?
Ai32
BString
CVec<T>
DBox<T>
What does Rust prevent by enforcing ownership rules in function calls?
AUse-after-free bugs
BSyntax errors
CInfinite loops
DType mismatches
Explain how ownership is transferred when passing variables to functions in Rust and how to avoid moving ownership.
Think about how & references work compared to normal variable passing.
You got /4 concepts.
    Describe what happens when a function returns a value it owns and how ownership is managed in that case.
    Consider how ownership moves back to the caller after the function finishes.
    You got /3 concepts.

      Practice

      (1/5)
      1. What happens when a function in Rust takes ownership of a variable passed to it?
      easy
      A. The function borrows the variable temporarily.
      B. The original variable can no longer be used after the function call.
      C. The variable is copied and both original and function have ownership.
      D. The variable is automatically cloned inside the function.

      Solution

      1. Step 1: Understand ownership transfer

        When a function takes ownership, the original variable's ownership moves to the function.
      2. Step 2: Effect on original variable

        After the function call, the original variable is no longer valid and cannot be used.
      3. Final Answer:

        The original variable can no longer be used after the function call. -> Option B
      4. Quick Check:

        Ownership moves = original invalid [OK]
      Hint: Ownership moves to function, original variable becomes unusable [OK]
      Common Mistakes:
      • Thinking ownership is copied, not moved
      • Confusing borrowing with ownership transfer
      • Assuming automatic cloning happens
      2. Which of the following function signatures correctly borrows a string slice without taking ownership?
      easy
      A. fn print_name(name: &str) { println!("{}", name); }
      B. fn print_name(name: &String) { println!("{}", name); }
      C. fn print_name(name: String) { println!("{}", name); }
      D. fn print_name(name: String) -> String { name }

      Solution

      1. Step 1: Identify borrowing syntax

        Borrowing a string slice uses &str type, which is a reference to string data.
      2. Step 2: Match function signature

        fn print_name(name: &str) { println!("{}", name); } uses &str, correctly borrowing without taking ownership.
      3. Final Answer:

        fn print_name(name: &str) { println!("{}", name); } -> Option A
      4. Quick Check:

        Borrow string slice = &str [OK]
      Hint: Use &str to borrow string slices, not String type [OK]
      Common Mistakes:
      • Using String type takes ownership
      • Using &String borrows but is less flexible than &str
      • Returning String does not borrow
      3. What is the output of the following Rust code?
      fn take_ownership(s: String) {
          println!("Inside: {}", s);
      }
      
      fn main() {
          let s = String::from("hello");
          take_ownership(s);
          println!("Outside: {}", s);
      }
      medium
      A. Inside: hello Outside: hello
      B. Inside: hello Outside:
      C. Inside: hello Compile error: use of moved value 's'
      D. Runtime error: use after free

      Solution

      1. Step 1: Analyze ownership transfer in function call

        The function take_ownership takes ownership of s, moving it inside the function.
      2. Step 2: Check usage after ownership moved

        After the function call, s is no longer valid in main, so using it causes a compile error.
      3. Final Answer:

        Inside: hello Compile error: use of moved value 's' -> Option C
      4. Quick Check:

        Ownership moved = compile error on use after move [OK]
      Hint: Using moved variable after function call causes compile error [OK]
      Common Mistakes:
      • Assuming variable is still valid after move
      • Expecting runtime error instead of compile error
      • Thinking variable is copied automatically
      4. Identify the error in this Rust code and choose the fix:
      fn add_one(num: &i32) -> i32 {
          *num + 1
      }
      
      fn main() {
          let x = 5;
          let y = add_one(x);
          println!("{}", y);
      }
      medium
      A. No error, code runs correctly.
      B. Change function parameter to num: i32 to take ownership.
      C. Change return type to &i32 to return a reference.
      D. Change call to add_one(&x) to pass a reference.

      Solution

      1. Step 1: Check function parameter type

        Function expects a reference &i32, but main passes x (i32) directly.
      2. Step 2: Fix function call

        Pass a reference &x to match parameter type and avoid type mismatch error.
      3. Final Answer:

        Change call to add_one(&x) to pass a reference. -> Option D
      4. Quick Check:

        Pass reference when function expects &i32 [OK]
      Hint: Match argument type with parameter type exactly [OK]
      Common Mistakes:
      • Passing value instead of reference
      • Changing return type unnecessarily
      • Ignoring compiler type mismatch errors
      5. Given this Rust code, what is the correct way to write a function that takes ownership of a vector, adds an element, and returns ownership back?
      fn add_element(vec: Vec<i32>) -> Vec<i32> {
          // Add 10 to the vector
          vec.push(10);
          vec
      }
      hard
      A. fn add_element(mut vec: Vec<i32>) -> Vec<i32> { vec.push(10); vec }
      B. fn add_element(vec: &Vec<i32>) -> Vec<i32> { vec.push(10); vec.clone() }
      C. fn add_element(vec: Vec<i32>) { vec.push(10); }
      D. fn add_element(vec: &mut Vec<i32>) { vec.push(10); }

      Solution

      1. Step 1: Understand ownership and mutability

        To modify the vector, the function must take ownership and have mutable access, so parameter must be mutable.
      2. Step 2: Return ownership after modification

        Return the modified vector to give ownership back to the caller.
      3. Final Answer:

        fn add_element(mut vec: Vec<i32>) -> Vec<i32> { vec.push(10); vec } -> Option A
      4. Quick Check:

        Mutable ownership + return ownership = fn add_element(mut vec: Vec<i32>) -> Vec<i32> { vec.push(10); vec } [OK]
      Hint: Use mut parameter and return vector to keep ownership [OK]
      Common Mistakes:
      • Forgetting mut keyword for parameter
      • Trying to modify borrowed vector without mut
      • Not returning the vector after modification
      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