sgldiv
sgldiv

Reputation: 643

How do I set the lifetime of a return value as the lifetime of the variable I move into it?

I am trying to teach myself some rust, and have written something that looks like:

let args:Vec<String> = env::args().collect();
let parsed = parser::sys(args.as_slice());

...

pub fn sys<'a>(args:&'a [String]) -> Parsed<'a> {
  parsed(args)
}

where parsed is a function that parses and loads configs.

This works fine. Now I am trying to abstract away explicitly calling env::args() and hide it in the call to sys , so I write a new version of sys

pub fn sys<'a>() -> Parsed<'a> {
  let args:Vec<String> = env::args().collect();
  parsed(args.as_slice())
}

And this fails with:

error: `args` does not live long enough
src/test.rs:66      parsed(args.as_slice())

I think the error is because there's no way for compiler to infer that I want the lifetime of this newly created struct to be the lifetime of the variable I want to move this into. Is this correct? How would I annotate the lifetime on this return value/fix this?

Upvotes: 16

Views: 12710

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300209

I think the error is because there's no way for compiler to infer that I want the lifetime of this newly created struct to be the lifetime of the variable I want to move this into.

Actually, no.

The error is because you are trying to create references into the variable args which will no longer be valid after you return from sys since args is a local variable and thus is dropped at the end of sys.

If you wish to use references, you could supply sys with a &'a mut Vec<String> (empty), fill it in sys, and return references to it:

pub fn sys<'a>(args: &'a mut Vec<String>) -> Parsed<'a> {
    *args = env::args().collect();
    parsed(args.as_slice())
}

which guarantees that args outlive the sys call. This will borrow args for the lifetime of the result.

Another solution is to do away with 'a and simply have Parsed own its elements rather than have references to them; however without the definition of Parsed I cannot advise how best to do so.

Upvotes: 11

Related Questions