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

Rust可变闭包使用疑惑:为何两种场景mut修饰要求不同?

Rust闭包的mut声明困惑:为什么直接调用要mut,传给函数不用?

核心原因:闭包的调用依赖自身的可变性

闭包捕获可变环境时,它的调用逻辑(对应FnMut trait的call_mut方法)要求&mut self权限。这直接导致两种场景的差异:

  • 如果你直接在当前作用域调用闭包,必须拥有闭包的可变借用权限——要么把闭包变量声明为mut,要么调用时显式可变借用(比如(&mut func)())。
  • 如果你把闭包传给其他函数,只要函数参数接受FnMut类型,函数内部会自动以可变方式处理闭包,不需要你在外部声明mut。

第一个示例:直接调用闭包需要mut

看你的第一段代码:

fn main() {     
    let mut list = vec![1, 2, 3];     
    let mut borrows_mutably = || list.push(7);       
    borrows_mutably();     
} 

这个闭包捕获了list的可变引用,属于FnMut() -> ()类型。当你直接调用borrows_mutably()时,本质是调用它的call_mut(&mut self)方法——这要求你对闭包变量拥有可变权限,所以必须把borrows_mutably声明为mut。

如果不声明mut,编译器会报错,因为你试图对一个不可变绑定的闭包执行可变操作(调用需要&mut self的方法)。

第二个示例:传给函数时无需mut

再看第二段代码:

fn main() {
    let mut num_ops = 0;
    let func = |r: &i32| {
        num_ops += 1;
        r.abs()
    };
    let mut list = [-3, 1, 5];
    list.sort_by_key(func);
    println!("{:?}, {}", list, num_ops);
}

sort_by_key的签名是:

pub fn sort_by_key<K, F>(&mut self, mut f: F)
where
    F: FnMut(&T) -> K,
    K: Ord,

它的参数是mut f: F——函数内部会把传入的闭包绑定为可变变量,因此可以直接调用闭包的call_mut方法,不需要你在外部把func声明为mut。

而如果自己直接调用func(),还是需要func是mut的,因为此时是你在当前作用域调用它的可变方法,必须持有可变权限。

总结

  • 闭包是否需要声明为mut,取决于你在当前作用域中是否需要对闭包执行可变操作(比如直接调用)。
  • 当闭包被传给接受FnMut的函数时,函数会负责处理闭包的可变借用,外部的闭包变量不需要额外声明mut。

内容的提问来源于stack exchange,提问作者Jaime Arboleda Castilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:33:10