以下示例代码无法编译:
fn invoke(i: i32, mut f: impl FnMut(i32)) {
f(i)
}
fn main() {
let f: fn(i32, _) = invoke;
let mut sum: i32 = 0;
for i in 0..10 {
_ = f(i, |x| sum += x);
}
println!("{:?}", sum);
}
编译器返回以下错误:
Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `sum` as mutable more than once at a time
--> src/main.rs:10:18
|
10 | _ = f(i, |x| sum += x);
| - ^^^ --- borrows occur due to use of `sum` in closure
| | |
| | `sum` was mutably borrowed here in the previous iteration of the loop
| first borrow used here, in later iteration of loop
For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground` due to previous error
如果我将f
赋值移到for
循环,代码编译:
fn invoke(i: i32, mut f: impl FnMut(i32)) {
f(i)
}
fn main() {
let mut sum: i32 = 0;
for i in 0..10 {
let f: fn(i32, _) = invoke;
_ = f(i, |x| sum += x);
}
println!("{:?}", sum);
}
我搞不懂为什么第一个代码不能编译.变量f
的类型为fn
,这意味着它是无状态的.变量f
也是不可变的,因此即使它的类型是有状态的,它也不能存储闭包.因此,编译器应该能够在for
循环的下一次迭代之前得出闭包将被删除的结论.然而,编译器的行为就像f
是可变的,并且它可以存储闭包.你能解释一下为什么编译器会这样做吗.
Rustc版本:稳定v1.68.2