You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调用集合中存储的FnMut?(编译错误:无法可变借用*handler)

修复Rust中FnMut闭包调用的可变借用错误

你遇到的错误核心是:FnMut类型的闭包调用时需要被可变借用,但你遍历的是scope.fn_list的不可变引用(&scope.fn_list),导致无法获得闭包的可变访问权限,进而无法调用闭包。

具体修复步骤

  1. 将scope声明为可变变量,因为需要对它的fn_list进行可变借用
  2. 遍历fn_list时使用可变引用(&mut scope.fn_list),这样能拿到闭包盒子的可变引用,满足FnMut的调用要求

修改后的完整代码

use std::collections::HashMap;

pub struct MyScope {
    pub fn_list: HashMap<String, Box<dyn FnMut(String)>>,
}

fn main() {
    let hello = "Hello";
    
    let closure = move |name: String|{
        println!("{} {}!", hello, name);
    };
    
    let mut list = HashMap::new();
    list.insert(
        "world".to_string(),
        Box::new(closure) as Box<dyn FnMut(String)>
    );
    
    // 声明可变的scope
    let mut scope = MyScope {
        fn_list: list
    };
    
    // 可变遍历fn_list
    for (name, handler) in &mut scope.fn_list {
        handler(name.clone());
    }
}

补充说明

FnMut trait的调用签名定义为fn(&mut self, args...) -> Output,调用闭包本质是调用这个方法,因此必须持有闭包的可变引用。当使用&mut scope.fn_list遍历时,每个handler都是&mut Box<dyn FnMut(String)>类型,Rust会自动处理解引用,让你可以直接调用闭包。

如果你的闭包不需要修改捕获的变量,也可以将类型改为Box<dyn Fn(String)>,这样遍历不可变引用也能调用,但FnMut的兼容性更强(支持后续修改捕获变量的场景)。

内容的提问来源于stack exchange,提问作者Nick Nizovtsev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:22:34