我正在尝试更改闭包内向量的元素:
pub struct Foo<'a, T> {
cb: Box<dyn FnMut(Vec<T>) + 'a>,
}
impl<'a, T> Foo<'a, T> {
pub fn new<F: FnMut(Vec<T>) + 'a>(cb: F) -> Self {
Self { cb: Box::new(cb) }
}
pub fn fun(&mut self, v: T) {
let vector = vec![v];
(self.cb)(vector);
}
}
fn main() {
let mut a = Vec::new();
let mut foo = Foo::new(move |v| {
for i in v {
a.push(i);
}
});
foo.fun(1);
println!("{:?}", a);
}
操场
我收到错误:
error[E0382]: borrow of moved value: `a`
--> src/main.rs:24:22
|
17 | let mut a = Vec::new();
| ----- move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
18 | let mut foo = Foo::new(move |v| {
| -------- value moved into closure here
19 | for i in v {
20 | a.push(i);
| - variable moved due to use in closure
...
24 | println!("{:?}", a);
| ^ value borrowed here after move
我知道 Rust 无法在闭包中复制a
的值,因为Vec
没有实现 traitCopy
,所以它必须移动它,并且a
移动为可变性使其以后无法使用println!
。
我是否正确存储了封盖?这里的使用寿命'a
正确吗?我应该将向量包装成Box
或Cell
之类的东西吗?
这是解决方案(游乐场(:
pub struct Foo<'a, T> {
cb: Box<dyn FnMut(Vec<T>) + 'a>,
}
impl<'a, T> Foo<'a, T> {
pub fn new<F: FnMut(Vec<T>) + 'a>(cb: F) -> Self {
Self {
cb: Box::new(cb),
}
}
pub fn fun(&mut self, v: T) {
let vector = vec![v];
(self.cb)(vector);
}
}
fn main() {
let mut a = Vec::new();
// new scope to make sure that `foo` isn't alive when `a` is borrowed later
{
// no `move` to prevent moving `a` into the closure
let mut foo = Foo::new(|v| {
a = v.clone();
});
foo.fun(1);
}
println!("{:?}", a);
}