Move closure execute twice

fn main() {
// Vec has non-copy semantics.
let haystack = vec![1, 2, 3];

let contains = move |needle| haystack.contains(needle);

println!("{}", contains(&1));
println!("{}", contains(&4));

}

What is your question?

Note that the move keyword is not required to make this example work. But with the move keyword, the Vec will no longer be directly usable because it is moved -- it will only be usable in the contains closure.

Well… you moved vector into a closure, so now it belongs to it… it can be executed as many times as you want, what's wrong with it?

The thing that I often see misunderstood about moving and closures is that there are two possible kinds of moves involved.

  • Moving a value into the closure, so that the closure owns it and the creator of the closure no longer does. The move keyword means that this is done even when borrowing would otherwise be chosen.
  • Moving a value out of the closure, so that the closure no longer owns it and something else does. This causes the closure to be callable only once (FnOnce).

Moving out requires moving in, but moving in doesn’t require moving out.

12 Likes

Amazing explanation!