@@ -426,39 +426,33 @@ use std::thread::Thread;
426
426
fn main () {
427
427
let mut numbers = vec! [1, 2, 3];
428
428
429
- for i in 0..3 {
430
- Thread::spawn (move || {
429
+ let guards: Vec < _ > = ( 0..3).map( | i | {
430
+ Thread::scoped (move || {
431
431
for j in 0..3 { numbers[j] += 1 }
432
432
});
433
- }
433
+ }).collect ();
434
434
}
435
435
` ` `
436
436
437
437
It gives us this error:
438
438
439
439
` ` ` text
440
- 6:71 error: capture of moved value: ` numbers`
441
- for j in 0..3 { numbers[j] += 1 }
442
- ^~~~~~~
443
- 7:50 note: ` numbers` moved into closure environment here
444
- spawn(move || {
445
- for j in 0..3 { numbers[j] += 1 }
446
- });
447
- 6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)
448
- for j in 0..3 { numbers[j] += 1 }
449
- ^~~~~~~~~~~~~~~
440
+ 7:29: 9:10 error: cannot move out of captured outer variable in an ` FnMut` closure
441
+ 7 Thread::scoped(move || {
442
+ 8 for j in 0..3 { numbers[j] += 1 }
443
+ 9 });
450
444
` ` `
451
445
452
- It mentions that " numbers moved into closure environment " . Because we
453
- declared the closure as a moving closure, and it referred to
454
- ` numbers` , the closure will try to take ownership of the vector. But
455
- the closure itself is created in a loop, and hence we will actually
456
- create three closures, one for every iteration of the loop. This means
457
- that all three of those closures would try to own ` numbers ` , which is
458
- impossible -- ` numbers` must have just one owner. Rust detects this
459
- and gives us the error: we claim that ` numbers ` has ownership, but our
460
- code tries to make three owners. This may cause a safety problem, so
461
- Rust disallows it.
446
+ It mentions that " captured outer variable in an ` FnMut ` closure " .
447
+ Because we declared the closure as a moving closure, and it referred
448
+ to ` numbers` , the closure will try to take ownership of the
449
+ vector. But the closure itself is created in a loop, and hence we will
450
+ actually create three closures, one for every iteration of the
451
+ loop. This means that all three of those closures would try to own
452
+ ` numbers ` , which is impossible -- ` numbers` must have just one
453
+ owner. Rust detects this and gives us the error: we claim that
454
+ ` numbers ` has ownership, but our code tries to make three owners. This
455
+ may cause a safety problem, so Rust disallows it.
462
456
463
457
What to do here? Rust has two types that helps us: ` Arc< T> ` and ` Mutex< T> ` .
464
458
* Arc* stands for " atomically reference counted" . In other words, an Arc will
@@ -480,14 +474,14 @@ use std::sync::{Arc,Mutex};
480
474
fn main () {
481
475
let numbers = Arc::new(Mutex::new(vec! [1, 2, 3]));
482
476
483
- for i in 0..3 {
477
+ let guards: Vec < _ > = ( 0..3).map( | i | {
484
478
let number = numbers.clone ();
485
- Thread::spawn (move || {
479
+ Thread::scoped (move || {
486
480
let mut array = number.lock().unwrap ();
487
481
array[i] += 1;
488
482
println! (" numbers[{}] is {}" , i, array[i]);
489
483
});
490
- }
484
+ }).collect() ;
491
485
}
492
486
` ` `
493
487
@@ -516,8 +510,10 @@ numbers[1] is 3
516
510
numbers[0] is 2
517
511
` ` `
518
512
519
- Each time, we get a slightly different output, because each thread works in a
520
- different order. You may not get the same output as this sample, even.
513
+ Each time, we can get a slithtly different output because the threads
514
+ are not quaranteed to run in any set order. If you get the same order
515
+ every time it is because each of these threads are very small and
516
+ complete too fast for their indeterminate behavior to surface.
521
517
522
518
The important part here is that the Rust compiler was able to use ownership to
523
519
give us assurance _at compile time_ that we weren' t doing something incorrect
@@ -539,13 +535,13 @@ safety check that makes this an error about moved values:
539
535
use std::thread::Thread;
540
536
541
537
fn main () {
542
- let vec = vec! [1, 2, 3];
543
-
544
- for i in 0..3 {
545
- Thread::spawn (move || {
546
- println! (" {}" , vec [i]);
538
+ let numbers = vec! [1, 2, 3];
539
+
540
+ let guards: Vec < _ > = ( 0..3).map( | i | {
541
+ Thread::scoped (move || {
542
+ println! (" {}" , numbers [i]);
547
543
});
548
- }
544
+ }).collect() ;
549
545
}
550
546
` ` `
551
547
0 commit comments