WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Advanced · question 50 of 100

What are the differences between Fn, FnMut, and FnOnce traits? Provide an example of when you would use each.?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

In Rust, closures are functions that can capture variables from the surrounding environment. When defining a closure, Rust has three different closures traits that can be used to specify how the closure captures variables and how it can be called. These traits are Fn, FnMut, and FnOnce.

1. The ‘Fn‘ trait indicates that the closure captures variables by reference. This means that the closure can call its environment without changing the state of the captured variables. This trait is also used for immutable borrowing, which enforces that the closure doesn’t modify the captured state.

Example usage:

    fn main() {
        let x = 42;
        let add = |y| x + y;
        println!("{}", add(8)); // 50
    }

In the example above, ‘add‘ is a closure that captures ‘x‘ by reference, which is indicated by the ‘Fn‘ trait. The closure can call ‘x‘ without changing its value.

2. The ‘FnMut‘ trait indicates that the closure captures variables by mutable reference. This means that the closure can modify the captured state. This trait is used for mutable borrowing.

Example usage:

    fn main() {
        let mut x = 42;
        let mut add = |y| {
            x += y;
            x
        };
        println!("{}", add(8)); // 50
        println!("{}", x); // 50
    }

In the example above, ‘add‘ is a closure that captures ‘x‘ by mutable reference, which is indicated by the ‘FnMut‘ trait. The closure can modify ‘x‘ by adding ‘y‘ to it.

3. The ‘FnOnce‘ trait indicates that the closure captures variables by value. This means that the closure takes ownership of the captured variables and can only be called once. This trait is used when the closure needs to take ownership of the variables in order to consume them.

Example usage:

    fn main() {
        let x = String::from("Hello");
        let takes_ownership = |s| {
            let len = s.len();
            println!("{} has length of {}", s, len);
        };
        takes_ownership(x); // closure takes ownership of x
        // println!("{}", x); // this will not compile, since x has been moved
    }

In the example above, ‘takes_ownership‘ is a closure that takes ownership of ‘x‘, which is a ‘String‘. The closure can consume ‘x‘ and use its value, but cannot be called again since it has taken ownership.

In summary, the differences between the ‘Fn‘, ‘FnMut‘, and ‘FnOnce‘ traits relate to how the closure captures variables and how it can be called. The ‘Fn‘ trait captures variables by reference and enforces immutable borrowing, ‘FnMut‘ captures variables by mutable reference and allows mutable borrowing, and ‘FnOnce‘ captures variables by value and consumes them.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics