In the Rust docs, there is a learning exercise about concurrency, with the following code:
let philosophers = vec![
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];
let handles: Vec<_> = philosophers.into_iter().map(|p| {
thread::spawn(move || {
p.eat();
})
}).collect();
for h in handles {
h.join().unwrap();
}
They explain each of its pieces briefly, but they don't explain why there is what seems to be a move
directive and a logical OR in the thread::spawn()
call:
This closure needs an extra annotation, move, to indicate that the closure is going to take ownership of the values it’s capturing.
However, this 'annotation' doesn't look anything like the other annotations, such as type. What's really going on here, and why? (Searching for that snippet of code doesn't seem to point back to anywhere but the same docs and other blog posts about other types of move
ing.)
A closure that captures by reference is of the form |ARGUMENTS| EXPRESSION
.
A closure that captures by value is of the form move |ARGUMENTS| EXPRESSION
.move
is a keyword that is only used in that location at present.
It is a little unfortunate that a closure accepting no arguments looks like the logical OR operator, but that’s the way it goes. There is no syntactic ambiguity from it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With