0

I'm doing some exercises with using threads in Rust. I want to print chunked string, but I can't get pass lifetimes issue I've stumbled upon. Here's my code:

let input = "some sample string".to_string();

let mut threads = vec![];
for chunk in input.chars().collect::<Vec<char>>().chunks(2) {
    threads.push(thread::spawn({
        move || -> () {
            println!("{:?}", chunk);
        }
    }))
}

When I'm trying to run it, I get a following error:

error[E0716]: temporary value dropped while borrowed
 --> src\main.rs:7:18
  |
7 |     for chunk in input.chars().collect::<Vec<char>>().chunks(2) {
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------
  |                  |                                            |
  |                  |                                            temporary value is freed at the end of this statement
  |                  creates a temporary which is freed while still in use
  |                  argument requires that borrow lasts for `'static`

I understand that the compiler doesn't know if the chunk within the thread will not outlive the input variable. But what I can do to fix this code? I've tried to clone() the vector, but it didn't help.

Djent
  • 2,877
  • 10
  • 41
  • 66
  • Does this answer your question? [How can I pass a reference to a stack variable to a thread?](https://stackoverflow.com/questions/32750829/how-can-i-pass-a-reference-to-a-stack-variable-to-a-thread) – trent Aug 30 '20 at 12:08

1 Answers1

5

The chunks are of the type &[char], with the same lifetime as the string.

Simply cloning here won't work, as at compile time it doesn't know the size of the char array. To get a owned copy of a unknown sized array, you must convert it to a Vec, which is done easily with the to_vec() function.

let input = "some sample string".to_string();

let mut threads = vec![];

for chunk in input.chars().collect::<Vec<char>>().chunks(2) {
    let owned_chunk = chunk.to_vec();
    threads.push(thread::spawn({
        move || -> () {
            println!("{:?}", owned_chunk);
        }
    }))
}

Alternatively, since we know the size of the array, we can create an array on the stack to copy into. This removes the need to allocate any heap memory.

let input = "some sample string".to_string();

let mut threads = vec![];

for chunk in input.chars().collect::<Vec<char>>().chunks(2) {
    let mut owned_array = ['\0'; 2];
    owned_array.copy_from_slice(chunk);
    threads.push(thread::spawn({
        move || -> () {
            println!("{:?}", owned_array);
        }
    }))
}
8176135
  • 3,755
  • 3
  • 19
  • 42