2

The intention is to take the output of calling a binary, get the last line of that output, split it, and get the string at index 1.

Here is the attempt:

    let result:Result<String, FromUtf8Error> = String::from_utf8(output.stdout);
    let value = result.map(move |res| {
        res.lines()
            .last()
            .unwrap_or(String::from("").as_ref())
            .split(" ")
            .collect::<Vec<&str>>()[1]
    });

Two issues:

First one, the above code leads to compilation error:

57 | /         res.lines()
58 | |             .last()
59 | |             .unwrap_or(String::from("").as_ref())
   | |                        ---------------- temporary value created here
60 | |             .split(" ")
61 | |             .collect::<Vec<&str>>()[1]
   | |______________________________________^ returns a value referencing data owned by the current function

second one, I realise the type of value is Result<<unknown>,FromUtf8Error> instead of it being Result<<String>,FromUtf8Error> as I expected.

So how to fix the compilation error and get the type right?

dade
  • 3,340
  • 4
  • 32
  • 53

1 Answers1

3

You Are trying to return a &str that is pointing to data owned by the map closure. Same thing as

fn does_not_work() -> &str {
    let my_string = String::new();
    &my_string
}

You need to have an owned value, such as String, to return with.

result.map(move |res| {
    String::from(
        res.lines()
        .last()
        .unwrap_or("")
        .split(" ")
        .collect::<Vec<&str>>()[1]
    )
})
pigeonhands
  • 3,066
  • 15
  • 26
  • Thanks! I got as much to using the move operator, but did not see the need to create another instance of String. – dade Jun 07 '20 at 10:47