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:
    rust Copy
    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:
    rust Copy
    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:
    rust Copy
    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

expert

What are the specific conditions for a closure to implement the Fn , FnMut and FnOnce traits?

middle

Does Rust support OOP?

middle

How to implement a custom Allocator in Rust?

Bình luận

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

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