Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

rust

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?

like image 410
sgldiv Avatar asked Feb 23 '15 10:02

sgldiv


People also ask

How do you calculate the lifetime value of a business?

The lifetime value is calculated as LTV = $80 x 4 x 2 = $640. Furthermore, the profit margin in the clothing store is 20%, hence the CLV is as follows: CLV = $80 x 4 x 2 x 20% = $128. The lifetime value figure can help a business estimate future cash flows and the number of customers they need to obtain to achieve profitability.

What is the lifetime of a variable?

The time during which a variable retains its value is known as its lifetime. The value of a variable may change over its lifetime, but it retains some value. When a variable loses scope, it no longer has a value.

What happens to the value of a variable when it expires?

The value of a variable may change over its lifetime, but it retains some value. When a variable loses scope, it no longer has a value. When a procedure begins running, all variables are initialized.

How do you calculate lifetime value of a clothing store?

Numerical Example. The average sales in a clothing store are $80 and, on average, a customer shops four times every two years. The lifetime value is calculated as LTV = $80 x 4 x 2 = $640. Furthermore, the profit margin in the clothing store is 20%, hence the CLV is as follows: CLV = $80 x 4 x 2 x 20% = $128.


1 Answers

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.

like image 86
Matthieu M. Avatar answered Oct 14 '22 16:10

Matthieu M.