HI Hongwei,
Ah, okay, Sorry, I misunderstood the original question (including Alexander's) !
Yes, you're quite right. In this case, `line` is a Copy-able trait, so the `move` would copy over `line` into the closure, but would not invalidate the local copy of `line` (inside `linum`). If `line` were not a Copy-able type, then, of course, the value would still be copied over to the closure as part of the `move`, but the
value in `linum` would now be invalidated. So the `move` part is sort of orthogonal to the actual mechanism of the move itself - it is required by the ownership system whether the value is Copyable or not, but the actual mechanism of the move would be copying over the value (I'm sure the compiler must do
some sort of copy elision/optimisations to mitigate the overhead as much as possible).
So, something like the following works:
fn foo () -> impl FnMut() -> () {
let mut line = 0; // copyable type
let baz = Box::new(move || {
line += 1;
println!("line is {}", line);
});
// local copy still works since the move
// only did a copy of a Copyable type
println!("local line is {}", line);
line += 100;
println!("local line is {}", line);
baz
}
fn main() {
let mut bar = foo();
bar();
bar();
}
whereas the following does not work since `Box<T>` is not a Copy-able type:
fn foo () -> impl FnMut() -> () {
let mut line = Box::new(0); // non-Copyable type
let baz = Box::new(move || {
*line += 1;
println!("line is {}", line);
});
// the Ownership system will not
// allow this since the move was
// done on a non-Copy type
println!("local line is {}", line);
*line += 100;
println!("local line is {}", line);
baz
}
fn main() {
let mut bar = foo();
bar();
bar();
}
Cheers,
Timmy