Problem with split in map function

When I try to run code below:

let stdin = std::io::stdin();
let lines: Vec<_> = stdin.lock().lines().map(|s| s.unwrap().split(' ')).collect();

I get this error:

error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:75:54
   |
75 |     let lines: Vec<_> = stdin.lock().lines().map(|s| s.unwrap().split(' ')).collect();
   |                                                      ----------^^^^^^^^^^^
   |                                                      |
   |                                                      returns a value referencing data owned by the current function
   |                                                      temporary value created here

I try do fix this problem in many ways. But I don't know what couse this problem. Can you give me advice how I can resolve this problem. ?

I haven't test it but maybe:

let lines: Vec<_> = stdin.lock().lines().into_iter().map(|s| s.unwrap().split(' ')).collect();

(added into_iter)

Nope. The compiler actually just tells you what the problem is. split returns an iterator that provides a view into (reference to substrings of) the string. However, since lines provides owned Strings, when you map over those strings, they get dropped at the end of the closure. So because s gets dropped at the end of the closure, you can't return a reference to a substring of s from the closure. You have to convert every one of them to an owned substring eagerly, like this:

    let lines: Vec<_> = stdin
        .lock()
        .lines()
        .map(|s| {
            s.unwrap()
            .split(' ')
            .map(str::to_owned)
            .collect::<Vec<_>>()
        })
        .collect();
3 Likes

It works. Thank you for good explanation.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.