2

After implementing the map-reduce example on rust-by-example, I tried to do the same thing but with the data stored in another file. The compiler now tells me that my data variable is borrowed with a 'static lifetime and does not live long enough. I'm not sure who is borrowing my 'data' and I am not sure how to respond to the compiler's help.

I've already tried adding all the type annotations to see if I had assumed a wrong type somewhere, but that didn't help. The same code works if data is a &'static str instead of a String.

use std::{fs, thread};

fn main() {
    let data = fs::read_to_string("data.txt").unwrap();
    let chunked_data = data.split_whitespace();

    let mut children = vec![];
    for chunk in chunked_data {
        children.push(thread::spawn(move || -> u32 {
            chunk.chars().map(|c| c.to_digit(10).unwrap()).sum()
        }));
    }

    let mut sums = vec![];
    for child in children {
        let sum = child.join().unwrap();
        sums.push(sum);
    }

    let res = sums.iter().sum::<u32>();
    println!("{}", res);
}
error[E0597]: `data` does not live long enough
  --> src/main.rs:5:24
   |
5  |     let chunked_data = data.split_whitespace();
   |                        ^^^^-------------------
   |                        |
   |                        borrowed value does not live long enough
   |                        argument requires that `data` is borrowed for `'static`
...
22 | }
   | - `data` dropped here while still borrowed

I'm sure this problem is easy to solve, but I can't seem to find out who is borrowing my data.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • *who is borrowing my `data`* — the error message points to the culprit: `split_whitespace`. From [its docs](https://doc.rust-lang.org/std/primitive.str.html#method.split_whitespace), emphasis mine: *The iterator returned will return string slices that are **sub-slices of the original string slice**, separated by any amount of whitespace* – Shepmaster Feb 01 '19 at 15:45

1 Answers1

1

The split_whitespace method operates on &strs which is an issue due to the move closure in the loop. A quick fix is to operate on owned Strings instead:

for chunk in chunked_data.map(|chunk| chunk.to_owned())
ljedrz
  • 20,316
  • 4
  • 69
  • 97
  • Proper fixes can be found in the duplicates ^^. – ljedrz Feb 01 '19 at 15:42
  • "Proper" is, as always, situation dependent. [Sharing String between threads in Rust](https://stackoverflow.com/q/42467829/155423) discusses the various possible solutions. – Shepmaster Feb 01 '19 at 15:43