这里出了什么问题?
fn main() {
// scope 1
let mut i = 0u32;
let _ = (0..2)
.map(|_| {
// scope 2
// error : captured variable cannot escape `FnMut` closure body
(0..2).map(|_| {
// scope 3
i += 1;
})
});
}
操场
完整错误为:
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:8:13
|
3 | let mut i = 0u32;
| ----- variable defined here
4 | let _ = (0..2)
5 | .map(|_| {
| - inferred to be a `FnMut` closure
...
8 | / (0..2).map(|_| {
9 | | // scope 3
10 | | i += 1;
| | - variable captured here
11 | | })
| |______________^ returns a reference to a captured variable which escapes the closure body
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
发生了什么事?
- 为什么将
move
添加到第二个闭包的参数列表中会使问题消失 - 完整的错误消息说;返回对脱离闭包主体"?"的捕获变量的引用;?但函数返回单位。那么鲁斯特在想什么呢?参考文献是什么?作用域3中的
i
真的是对作用域2中作用域1中i
的不可见引用的引用吗 - 为什么将第二个
map
更改为for_each
会使问题消失
在内部map()
的末尾添加分号可以解决问题:包含对i
的可变引用的内部map()
不会返回到外部map()
,但您需要迭代这些map()
才能更改i
。
在内部map()
中使用move
通过将i
复制到闭包中来消除对i
的引用,使得增量对原始i
没有影响。
我真的不理解你的初衷,但这似乎奏效了:
fn main() {
let mut i = 0u32;
let outer = (0..2).map(|_| {
let inner = (0..2).map(|_| {
i += 1;
});
for inner_elem in inner {
println!("inner_elem={:?}", inner_elem);
}
});
for outer_elem in outer {
println!("outer_elem={:?}", outer_elem);
}
println!("i={:?}", i);
}
/*
inner_elem=()
inner_elem=()
outer_elem=()
inner_elem=()
inner_elem=()
outer_elem=()
i=4
*/