Reputation: 643
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
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