Rust Ownership, Borrowing, and Lifetimes Fundamentals Quiz Quiz

Explore key concepts of Rust's ownership model, borrowing mechanisms, and lifetime annotations with this engaging quiz. Strengthen your understanding of safe memory management in Rust while testing your knowledge of borrowing rules, mutability, references, and how lifetimes prevent bugs.

  1. Understanding Ownership Transfer

    What happens when a variable in Rust is assigned to another variable, such as 'let y = x;' for a non-Copy type like String?

    1. Both x and y can use the value freely
    2. The value is cloned automatically
    3. x gets reset to its default value
    4. Ownership of the value is moved from x to y

    Explanation: In Rust, assigning a non-Copy type like String to another variable transfers, or moves, ownership to the new variable, making the original variable invalid. The variables cannot both use the value; doing so causes a compilation error. Automatic cloning does not occur on simple assignment unless explicitly called. Rust does not reset the value to a default; it simply transfers ownership.

  2. Borrowing and References

    Which syntax correctly borrows a variable 'data' immutably in Rust?

    1. *data
    2. datau0026
    3. u0026data
    4. u0026u0026data

    Explanation: The ampersand 'u0026' before a variable creates an immutable reference, which is called borrowing in Rust. Using '*data' attempts to dereference, while 'datau0026' is invalid syntax. 'u0026u0026data' makes a reference to a reference, which is not the basic borrowing pattern. Therefore, 'u0026data' is the correct choice.

  3. Mutable Borrowing Rules

    What restriction does Rust enforce when a variable has been mutably borrowed (e.g., let m = u0026mut num;)?

    1. Multiple mutable references are allowed simultaneously
    2. Only immutable references are allowed alongside
    3. No other references, mutable or immutable, are allowed at the same time
    4. The variable becomes unusable forever

    Explanation: Rust ensures safe memory access by allowing only one mutable reference, and no other references, to a value at any moment. Allowing only immutable references excludes having a mutable reference at the same time. Multiple mutable references simultaneously are forbidden because they risk data races. The variable does not become unusable forever; access resumes after the borrow ends.

  4. Borrow Checker Purpose

    Why does Rust's borrow checker exist in the compilation process?

    1. To decrease code readability
    2. To run background garbage collection
    3. To prevent data races and dangling references at compile time
    4. To automatically generate code for memory deallocation

    Explanation: The borrow checker is a compile-time feature that checks reference rules to avoid issues like data races and dangling references. It does not generate or execute code for memory allocation. Its role is not to decrease readability; rather, it helps ensure code safety. Rust does not use a background garbage collector.

  5. Lifetime Annotation Syntax

    Which of the following is the correct way to annotate a lifetime for a reference parameter in a Rust function?

    1. fnu003C'au003E get(input: u0026str) -u003E u0026str
    2. fn getu003C'au003E(input: u0026'a str) -u003E u0026'a str
    3. fn get(input: u0026str) -u003Eu003C'au003E u0026str
    4. fn get(input: u0026stru003C'au003E) -u003E u0026stru003C'au003E

    Explanation: The lifetime annotation must appear after the function name in angle brackets, and each reference type using the lifetime must be annotated the same way. The other options mix the syntax for references and lifetimes incorrectly, or place the annotation in the wrong position. Only the first option shows Rust's lifetime annotation syntax correctly.

  6. Dangling References

    What triggers a dangling reference error in Rust code?

    1. Returning a reference to a value that goes out of scope
    2. Calling a function recursively
    3. Declaring a variable without initializing it
    4. Using the wrong data type

    Explanation: A dangling reference occurs when a reference points to memory that is no longer valid, such as returning a reference to a local variable inside a function. Declaring an uninitialized variable is a different type of error, not a dangling reference. Using the wrong data type results in a type error, while recursion does not cause dangling references by itself.

  7. Copy Trait and Ownership

    Which type below implements the Copy trait, so assignment does not move ownership?

    1. Vecu003Ci32u003E
    2. Boxu003Ci32u003E
    3. String
    4. i32

    Explanation: Primitive types like i32 implement the Copy trait, meaning their values are duplicated safely on assignment rather than moved. Complex types like String, Vecu003Ci32u003E, and Boxu003Ci32u003E do not implement Copy by default, as their data is allocated on the heap and requires explicit cloning for duplication. Only i32 is automatically duplicated.

  8. Function Parameters and Ownership

    Given 'fn takes_ownership(s: String)' in Rust, what happens to the variable passed as 's' after the function call?

    1. Ownership of the value is transferred to the function parameter
    2. It is turned into a reference
    3. The value is copied back to the caller automatically
    4. It can be safely used after the function call as before

    Explanation: Passing a String (non-Copy type) by value to a function transfers ownership to the parameter inside the function. Attempting to use the original variable afterward will result in a compile-time error. There is no implicit copying or conversion to a reference unless explicitly stated. Automatic copying only happens with types that implement Copy.

  9. Valid Reference Scope

    When is it safe to return a reference from a function in Rust?

    1. Only for global variables
    2. When the referenced value lives longer than the returned reference
    3. Whenever the type is primitive
    4. If the function is marked as 'unsafe'

    Explanation: Rust ensures reference safety by requiring that referenced values outlive any references returned. It is a mistake to assume primitives can be referenced without considering lifetimes. Returning references to global variables is allowed but is not a universal rule for safety. Marking a function as 'unsafe' does not bypass lifetime checks for safe code.

  10. Simultaneous References

    Which statement is true about having multiple references to a value in Rust?

    1. Immutable references require lifetime annotations in all cases
    2. Only one reference at a time is allowed, regardless of mutability
    3. You can have many immutable references or one mutable reference, but not both at the same time
    4. Multiple mutable and immutable references can coexist without restriction

    Explanation: Rust's borrowing rules allow any number of immutable references, or one mutable reference, but never both at the same time. Limiting to a single reference of any kind is too strict and incorrect. Allowing simultaneous mutable and immutable references is unsafe and disallowed. Lifetime annotations for immutable references are often inferred and not always required.