关于临时闭包被错误推断为未实现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
相关产品推荐
相关产品推荐

