У меня есть фрагмент кода, который не компилируется:
struct A {
x: [u32; 10],
}
impl A {
fn iter<'a>(&'a self) -> impl Iterator<Item = u32> + 'a {
(0..10).map(|i| self.x[i])
}
}
fn main() {}
( детская площадка )
Компилятор говорит:
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
--> src/main.rs:7:21
|
7 | (0..10).map(|i| self.x[i])
| ^^^ ---- `self` is borrowed here
| |
| may outlive borrowed value `self`
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
|
7 | (0..10).map(move |i| self.x[i])
| ^^^^^^^^
Что я должен сделать, чтобы сделать эту работу?Мне нужно self
позже, поэтому я не могу переместить его, как предлагает компилятор.
Редактировать : Я полагал, что move
создаст проблемы при использовании self
позже.Например, см. Код:
struct A {
x: [u32; 3],
}
impl A {
fn iter<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
(0..3).filter(move |&i| self.x[i] != 0).map(move |i| self.x[i])
}
}
fn main() {
let a = A { x : [0, 1, 2]};
for el in a.iter() {
println!("{}", el);
}
}
( детская площадка )
Здесь &'a self
перемещается дважды, так что в действительности оба затвора стали собственниками&'a self
.Код на самом деле компилируется, но я не ожидал, что после его перемещения переменная больше не будет использоваться.В книге ( соответствующий раздел ) также приведен пример, подтверждающий мое понимание:
fn main() {
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x;
println!("can't use x here: {:?}", x);
let y = vec![1, 2, 3];
assert!(equal_to_x(y));
}
Этот код не компилируется.Почему мой код итератора работает с move
?