I know what move
is for and it makes sense to me, but I am puzzled by the behavior of capturing something that is Copy
.
For instance the following code compiles
#[derive(Debug, Clone, Copy)]
struct MyType (usize);
fn take<T>(t: T) {}
fn main() {
let v = MyType(0);
let ok = || take(v);
ok();
println!("Hello, world! {:?}", v);
}
This makes perfect sense since we will never move MyType
but always copy. And removing the Copy
trait results in compilation error.
However the following code doesn't compile
fn main() {
let pairs = vec![(1, 2), (2, 3), (3, 4)];
let x = vec![1, 2, 3];
let wtf = pairs.iter().flat_map(|&(from, to)| x.iter().map(|_| from));
}
The compiler complains that I borrowed from
and suggests me to add the move
keyword. I added it and it compiles.
fn main() {
let pairs = vec![(1, 2), (2, 3), (3, 4)];
let x = vec![1, 2, 3];
let wtf = pairs.iter().flat_map(|&(from, to)| x.iter().map(move |_| from));
}
This really puzzled me, when do we need the move
keyword? Why does the first one compiles but not the second one? Please correct me if I understand anything wrong, thank you very much!
Ah, I guess I see why, in the first example I call take()
which forced the copy?