Skip to content

Commit

Permalink
clarify that the map-reduce example relies on static data (#1592)
Browse files Browse the repository at this point in the history
The map-reduce example currently says "Because we're `move`-ing the data
segments into the thread, Rust will also ensure the data is kept alive
until the threads exit." Both halves of that sentence are true by
themselves, but I think the "because" is misleading. The main reason
Rust isn't giving us lifetime errors here is that the original `data`
string is a `&'static str` constant. The `move` keyword is important for
_keeping_ the data static (by capturing `&str` instead of `&&str`), but
it's not what _made_ the data static. If you force the data to be
non-static, like by adding `.to_string()` to the end of it, you can see
that even with `move` this example doesn't compile:

    error[E0597]: `data` does not live long enough
      --> src/main.rs:31:24
       |
    31 |       let chunked_data = data.split_whitespace();
       |                          ^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
    ...
    55 |           children.push(thread::spawn(move || -> u32 {
       |  _______________________-
    56 | |             // Calculate the intermediate sum of this segment:
    57 | |             let result = data_segment
    58 | |                 // iterate over the characters of our segment..
    ...  |
    70 | |             result
    71 | |         }));
       | |__________- argument requires that `data` is borrowed for `'static`
    ...
    89 |   }
       |   - `data` dropped here while still borrowed
  • Loading branch information
oconnor663 authored Aug 10, 2022
1 parent 73350e7 commit 311f669
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/std_misc/threads/testcase_mapreduce.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ its tiny block of digits, and subsequently we will sum the intermediate sums pro
thread.

Note that, although we're passing references across thread boundaries, Rust understands that we're
only passing read-only references, and that thus no unsafety or data races can occur. Because
we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive
until the threads exit, so no dangling pointers occur.
only passing read-only references, and that thus no unsafety or data races can occur. Also because
the references we're passing have `'static` lifetimes, Rust understands that our data won't be
destroyed while these threads are still running. (When you need to share non-`static` data between
threads, you can use a smart pointer like `Arc` to keep the data alive and avoid non-`static`
lifetimes.)

```rust,editable
use std::thread;
Expand Down

0 comments on commit 311f669

Please sign in to comment.