0

I have the following code ...

use std::process::Command;

fn main() {
    let cmds = vec![vec!["ls", "-lh"], vec!["grep", "foo"]];
    let mut processes: Vec<&mut Command> = Vec::new();

    let mut i = 0;
    let length = cmds.len();
    while i < length {
        let cmd = cmds[i].clone();
        let mut p = Command::new(&cmd[0]).args(&(cmd[1..]));
        processes.push(p);
        i += 1;
    }
    println!("processes: {:?}", processes);

    // want to manipulate processes elements here again.
    // ...
}

Which doesn't compile:

error: borrowed value does not live long enough
  --> src/main.rs:11:60
   |
11 |         let mut p = Command::new(&cmd[0]).args(&(cmd[1..]));
   |                     ---------------------                  ^ temporary value dropped here while still borrowed
   |                     |
   |                     temporary value created here
...
19 | }
   | - temporary value needs to live until here
   |
   = note: consider using a `let` binding to increase its lifetime

I understand why it refused to compile, I just don't know how to fix it in this case.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
mitnk
  • 3,127
  • 2
  • 21
  • 28
  • [You](http://stackoverflow.com/q/28820781/155423) cannot [extend](http://stackoverflow.com/q/27570978/155423) the [lifetime](http://stackoverflow.com/q/35666024/155423) of a [reference](https://stackoverflow.com/q/30330697/155423), **period**. – Shepmaster Mar 20 '17 at 01:06
  • The question marked answered this (duplicated) one is not quite match (the solution part is not clear at least to my question), but [this one](http://stackoverflow.com/a/35673760/665869) did answer my question in a way. Thanks for the links! – mitnk Mar 20 '17 at 04:01

1 Answers1

1

Instead of storing a borrowed reference, you could store the Command object itself.

let cmds = vec![vec!["ls", "-lh"], vec!["grep", "foo"]];
let mut processes: Vec<Command> = Vec::new();
// ^ you can store concrete objects instead of references.

for cmd in &cmds {
// ^ prefer a `for` loop over a `while` loop. (Also, you don't need to clone the cmds)
    let mut p = Command::new(cmd[0]);
    p.args(&cmd[1..]);
    // ^ you can get a concrete `Command` instead of `&mut Command` reference
    //   if you store the returned object from `new()`.
    processes.push(p);
}

println!("processes: {:?}", processes);
// processes: ["ls" "-lh", "grep" "foo"]
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005