我有一个创建 FnMut
闭包的函数,move
- 捕获其中一个参数。我收到编译器错误,因为参数不是 mut
。我不明白问题是什么,因为我移动
它并且闭包并没有真正使用参数本身。
代码:
pub struct Position {
pub x: usize,
pub y: usize,
}
fn map_it(p: Position) -> impl FnMut(usize) -> usize {
move |param| {
p.x += 1;
p.x + p.y + param
}
}
错误:
error[E0594]: cannot assign to `p.x`, as `p` is not declared as mutable
--> src/lib.rs:8:9
|
6 | fn map_it(p: Position) -> impl FnMut(usize) -> usize {
| - help: consider changing this to be mutable: `mut p`
7 | move |param| {
8 | p.x += 1;
| ^^^^^^^^ cannot assign
最佳答案
即使移动了变量 p
,您也没有引入新的变量绑定(bind)。绑定(bind) p
是不可变的,因此您不能通过 p
改变值。
闭包实际上是一个看起来(有点)像这样的结构:
struct MyClosure {
p: Position,
}
impl FnMut<usize, usize> for MyClosure {
fn call_mut(&mut self, param: usize) -> usize {
self.p.x += 1;
self.p.x + p.y + param
}
}
由此看来,p
应该在闭包内部是可变的,这绝对是令人信服的。
但是,Rust 避免直接公开此实现细节。变量 p
的可变性语义是词法的,就像闭包主体是外部函数的一部分一样。
您无法在闭包中使此变量可变。相反,您需要使原始 p
可变或在闭包外部引入新的可变绑定(bind)。
关于rust - 为什么我不能可变地移动捕获不可变变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57381861/