I'm using getopts, and I was previously getting a value from a flag like this:
let file = matches.opt_str("f").unwrap();
let file_path = Path::new(&file);
But, I would like to handle the possible errors better, by making the path optional. This is my new code:
let file = matches.opt_str("f");
let file_path = match file {
Some(f) => Some(Path::new(&f)),
None => None
}
But, when I try to compile this code, I get the error 'f' does not live long enough
. I'm completely stumped.
Heres the MCVE of my code:
use std::path::Path;
fn main() {
let foo = Some("success".to_string());
let string = match foo {
Some(s) => Some(Path::new(&s)),
None => None
};
}
error[E0597]: `s` does not live long enough
--> src/main.rs:6:35
|
5 | let string = match foo {
| ------ borrow later stored here
6 | Some(s) => Some(Path::new(&s)),
| ^^ - `s` dropped here while still borrowed
| |
| borrowed value does not live long enough
The issue arises because you are taking ownership of the contents of the Option
in your match with the binding s
(which uses bind-by-value). However, since nothing uses s
after the match arm, it would be dropped and cause a invalid reference, so it's prevented.
Instead, you could bind-by-reference:
let string = match foo {
Some(ref s) => Some(Path::new(s)),
None => None,
};
You could also get an Option<&T
> from the Option<T>
using as_ref
:
let string = match foo.as_ref() {
Some(s) => Some(Path::new(s)),
None => None,
};
I'd probably use the last solution coupled with map
:
let string = foo.as_ref().map(Path::new);
In modern Rust, you can leverage match ergonomics and match on the &Option<T>
:
let string = match &foo {
Some(s) => Some(Path::new(s)),
None => None,
};
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With