Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of the `move ||` idiom?

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 moveing.)

like image 668
bright-star Avatar asked Dec 25 '22 16:12

bright-star


1 Answers

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.

like image 71
Chris Morgan Avatar answered Dec 31 '22 02:12

Chris Morgan