I want to change a mutable variable in multiple threads. I know this would not be thread-safe, but I want to know how the Rust compiler will deal with it. So I use a range's map function to spawn sub-threads:
use std::thread;
fn break_law(value: &mut i32) {
*value += 20;
}
fn main() {
let mut x = 10;
let handles = (0..10).map(|| {
thread::spawn(move || {
break_law(&mut x);
println!("{:?}", x);
})
}).collect();
for h in handles {
h.join().unwrap();
}
}
But I get an error:
break_law1.rs:10:24: 15:4 error: type mismatch: the type `[closure@break_law1.rs
:10:28: 15:3 x:_]` implements the trait `core::ops::FnMut<()>`, but the trait `c
ore::ops::FnMut<(_,)>` is required (expected tuple, found ()) [E0281]
break_law1.rs:10 let handles = (0..10).map(|| {
break_law1.rs:11 thread::spawn(move || {
break_law1.rs:12 break_law(&mut x);
break_law1.rs:13 println!("{:?}", x);
break_law1.rs:14 })
break_law1.rs:15 }).collect();
break_law1.rs:10:24: 15:4 help: run `rustc --explain E0281` to see a detailed ex
planation
break_law1.rs:10:24: 15:4 error: type mismatch: the type `[closure@break_law1.rs
:10:28: 15:3 x:_]` implements the trait `core::ops::FnOnce<()>`, but the trait `
core::ops::FnOnce<(_,)>` is required (expected tuple, found ()) [E0281]
break_law1.rs:10 let handles = (0..10).map(|| {
break_law1.rs:11 thread::spawn(move || {
break_law1.rs:12 break_law(&mut x);
break_law1.rs:13 println!("{:?}", x);
break_law1.rs:14 })
break_law1.rs:15 }).collect();
break_law1.rs:10:24: 15:4 help: run `rustc --explain E0281` to see a detailed ex
planation
break_law1.rs:15:5: 15:14 error: type mismatch: the type `[closure@break_law1.rs
:10:28: 15:3 x:_]` implements the trait `core::ops::FnMut<()>`, but the trait `c
ore::ops::FnMut<(_,)>` is required (expected tuple, found ()) [E0281]
break_law1.rs:15 }).collect();
^~~~~~~~~
break_law1.rs:15:5: 15:14 help: run `rustc --explain E0281` to see a detailed ex
planation
break_law1.rs:18:6: 18:14 error: the type of this value must be known in this co
ntext
break_law1.rs:18 h.join().unwrap();
^~~~~~~~
break_law1.rs:17:2: 19:3 note: in this expansion of for loop expansion
error: aborting due to 4 previous errors
According to the info above, I get that range's map function definition is like this:
// Creates a new iterator that will apply the specified function to each
// element returned by the first, yielding the mapped element instead.
fn map<B, F>(self, f: F) -> Map<Self, F>
where F: FnMut(Self::Item) -> B
This looks odd, but how should I correct this? And why?