MST

星途 面试题库

面试题:Rust中FnMut trait在复杂场景下与可变闭包的协同

假设有一个结构体,其内部包含一个可变闭包成员,在结构体的方法中需要多次调用这个可变闭包并对其状态进行修改。请实现这个结构体及其方法,同时解释在这个过程中FnMut trait是如何保证可变闭包的正确行为以及避免数据竞争的。
31.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
struct MyStruct {
    closure: Box<dyn FnMut() -> i32>
}

impl MyStruct {
    fn new(closure: Box<dyn FnMut() -> i32>) -> Self {
        MyStruct {
            closure
        }
    }

    fn call_closure_multiple_times(&mut self) -> i32 {
        let mut result = 0;
        for _ in 0..3 {
            result += (self.closure)();
        }
        result
    }
}

关于FnMut trait

  1. 保证可变闭包正确行为
    • 在Rust中,FnMut trait允许闭包通过可变引用捕获其环境中的变量。对于结构体中的可变闭包成员closure,实现FnMut trait意味着闭包可以修改其捕获的状态。例如,闭包内部可能维护一个计数器,每次调用闭包时计数器增加,通过FnMut trait,闭包就可以正确地修改这个计数器。
    • 当我们在call_closure_multiple_times方法中多次调用self.closure时,FnMut trait确保每次调用都能按照闭包内部定义的逻辑修改闭包的状态,并且能够正确地返回结果。
  2. 避免数据竞争
    • Rust的所有权系统是避免数据竞争的核心。FnMut trait通过限制可变闭包的访问来避免数据竞争。当闭包被FnMut trait约束时,在同一时间只能有一个可变引用访问闭包。
    • call_closure_multiple_times方法中,self是可变引用,因为闭包是结构体的成员,所以只有这个方法可以在同一时间对闭包进行可变访问。如果有其他代码尝试同时对闭包进行可变访问,Rust编译器会报错,从而有效地避免了数据竞争。