Rust 为什么我能够调用闭包两次,即使我已经将一个变量移到了闭包中?
我在这里添加了Rust 为什么我能够调用闭包两次,即使我已经将一个变量移到了闭包中?,rust,closures,move-semantics,Rust,Closures,Move Semantics,我在这里添加了move来捕获a,但是我仍然能够调用x闭包两次。a在这里仍然作为可变引用借用吗?为什么不移动强制移动 变量a确实已移动到闭包中: fn main() { let mut a = String::from("dd"); let mut x = move || { a.push_str("string: &str"); }; x(); x(); } 错误[E0382]:移动值的借用:`a` -->src/main.rs:
move
来捕获a
,但是我仍然能够调用x
闭包两次。a
在这里仍然作为可变引用借用吗?为什么不移动强制移动 变量a
确实已移动到闭包中:
fn main() {
let mut a = String::from("dd");
let mut x = move || {
a.push_str("string: &str");
};
x();
x();
}
错误[E0382]:移动值的借用:`a`
-->src/main.rs:9:5
|
2 |设mut a=String::from(“dd”);
|----发生移动是因为'a'的类型为'std::string::string',而该类型不实现'Copy'特性
3 |让mut x=移动| |{
|------此处将值移到闭包中
4 | a.push_str(“字符串:&str”);
|-因在闭包中使用而移动的变量
...
9 | a.len();
|^移动后在此借用的价值
不清楚为什么您认为闭包x
在调用后会变得无效,但事实并非如此。与应用于结构的情况相同:
fn main() {
let mut a = String::from("dd");
let mut x = move || {
a.push_str("string: &str");
};
x();
x();
a.len();
}
这个问题源于我对闭包的错误理解。铁锈书中记录闭包的方式也导致了混淆(我不是说这本书不好)。如果其他人也有同样的混淆,下面是我的发现 闭包不仅仅存储作用域并在调用时运行它。它以首选方式捕获环境。包含
a
的环境存储在闭包中。从环境中捕获值的方式决定了特性
a
的值持续存在,直到闭包存在,除非某些操作将其移动,例如如果闭包返回a
或某个方法消耗a
。在这里,没有任何操作将a
移出闭包,因此可以根据需要多次调用闭包
可以从
FnOnce
、FnMut
和Fn
特征中获得更好的理解。这些特征取决于闭包捕获变量的方式,而不是变量如何移动到闭包中。FnMut
可以在值为move
d的闭包上实现。a
已移动到闭包。因此不应该在闭包调用结束时删除a
吗?这难道不是FnOnce
只能调用一次的原因吗?等效的move
ClosureLike
实现应该有`fn调用(mut self){`it right to moveself
not borrow.@raj no,当闭包被删除时,它将被删除。这里的闭包实现了FnMut
;它可以被多次调用。请参见@raj保持其余语义不变,这里是FnOnce
。错误是不言自明的。
struct ClosureLike {
a: String,
}
impl ClosureLike {
fn call(&mut self) {
self.a.push_str("string: &str");
}
}
fn main() {
let a = String::from("dd");
let mut x = ClosureLike { a };
x.call();
x.call();
}