Câu hỏi phỏng vấn Rust
Câu hỏi

Explain the use of Fn / FnMut /...

Câu trả lời

The Fn, FnMut, and FnOnce traits in Rust are used to define and work with closures, which are anonymous functions that can capture variables from their surrounding environment. These traits determine how closures can be called and what kind of access they have to the captured variables. Here's a detailed explanation of each trait and their use:

FnOnce

  • Definition: The FnOnce trait is the most permissive of the three. It represents closures that can be called at least once. This trait is implemented by closures that consume the captured variables, meaning they take ownership of these variables.
  • Usage: Use FnOnce when you need to call a closure that might consume its environment. This is useful for operations that need to take ownership of the captured variables, such as moving them out of the closure.
  • Example:
    fn consume_with_relish<F>(func: F)
    where
        F: FnOnce() -> String,
    {
        println!("Consumed: {}", func());
    }
    
    let x = String::from("x");
    let consume_and_return_x = move || x;
    consume_with_relish(consume_and_return_x);

FnMut

  • Definition: The FnMut trait is a subtrait of FnOnce and represents closures that can be called multiple times but may mutate the captured variables. These closures take mutable references to their environment.
  • Usage: Use FnMut when you need to call a closure multiple times and allow it to mutate its environment. This is useful for operations that need to modify the captured variables.
  • Example:
    fn do_twice<F>(mut func: F)
    where
        F: FnMut(),
    {
        func();
        func();
    }
    
    let mut x = 1;
    let mut add_two_to_x = || x += 2;
    do_twice(add_two_to_x);
    assert_eq!(x, 5);

Fn

  • Definition: The Fn trait is the most restrictive and is a subtrait of FnMut. It represents closures that can be called multiple times without mutating their environment. These closures take immutable references to their environment.
  • Usage: Use Fn when you need to call a closure multiple times without allowing it to mutate its environment. This is useful for read-only operations.
  • Example:
    fn call_with_one<F>(func: F) -> usize
    where
        F: Fn(usize) -> usize,
    {
        func(1)
    }
    
    let double = |x| x * 2;
    assert_eq!(call_with_one(double), 2);

Hierarchical Relationship

  • FnOnce is the most general trait, and any closure that implements Fn or FnMut also implements FnOnce.
  • FnMut is more restrictive than FnOnce but less restrictive than Fn. Any closure that implements...
senior

senior

Gợi ý câu hỏi phỏng vấn

middle

Does Rust support OOP?

junior

What happens when you pass a String to a function in Rust?

junior

Explain what is the relationship between Lifetimes and Borrow Checkers in Rust?

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào