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

关于临时闭包被错误推断为未实现Fn trait的问题咨询

临时闭包被错误推断为未实现Fn trait的问题咨询

大家好,我碰到了一个Rust编译器的诡异问题:当闭包作为临时实例直接在map方法中定义时,编译器错误地推断它只实现了FnMut trait,而不是我预期的Fn trait,导致类型不匹配的编译错误。

下面是我简化后的测试代码:

fn takes_fn_map<I, F, A, B>(_: std::iter::Map<I, F>)
where
    F: Fn(A) -> B,
{
}

fn main() {
    let map_temp_f = vec![0].into_iter().map(|x| x + 1);

    let var_f = |x| x + 1;
    let map_var_f = vec![0].into_iter().map(var_f);

    fn fn_f(x: i32) -> i32 {
        x + 1
    }
    let map_fn_f = vec![0].into_iter().map(fn_f);

    takes_fn_map(map_temp_f); // ! 编译错误
    takes_fn_map(map_var_f); // 正常通过
    takes_fn_map(map_fn_f); // 正常通过
}

编译这段代码时,只有第一个调用takes_fn_map(map_temp_f)会报错,错误信息如下:

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
  --> src/main.rs:8:46
   |
8  |     let map_temp_f = vec![0].into_iter().map(|x| x + 1);
   |                                              ^^^^^^^^^ this closure implements `FnMut`, not `Fn`
   |
note: required by a bound in `takes_fn_map`
  --> src/main.rs:1:20
   |
1  | fn takes_fn_map<I, F, A, B>(_: std::iter::Map<I, F>)
   |                    ^ required by this bound in `takes_fn_map`

我实在想不通:这个临时闭包没有捕获任何外部变量,也没有修改任何环境状态,按道理应该同时实现Fn、FnMut和FnOnce才对,为什么编译器只推断它实现了FnMut呢?而把闭包先赋值给变量再使用,或者直接使用普通函数就完全没问题,这两种情况编译器都能正确识别出它们满足Fn trait的约束。

有没有大佬能解释下这个现象,或者告诉我这是不是Rust编译器的一个bug?

备注:内容来源于stack exchange,提问作者lighthouse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 09:07:57