Reputation: 1257
I find Option
to be somewhat confusing when it comes to lifetime scoping on variables. I've been trying to extract the underlying value from Some
inside of an Option
match pattern like so:
let filename = match canonicalize(&PathBuf::from(filename)).unwrap().to_str() {
Some(path) => path,
_ => "",
};
// Later, I validate the string content
if filename.is_empty() {
do_something();
}
However, this throws the following error:
temporary value dropped while borrowed: borrow later used here
The documentation doesn't give much insight on how to persist lifetimes outside of the scope of the call they're initialized in. I have seen examples here and here. Both examples imply either throwing out the value, or converting to an Option
, neither of which I want. I simply want to get to the underlying &str
value once the function succeeds.
Upvotes: 3
Views: 1964
Reputation: 98348
Your problem is not with the Option
itself, but with the temporaries your code creates. Your main line is quite long, so lets dissect it a bit:
let temp: PathBuf = conicalize(PathBuf::from(filename)).unwrap();
let filename: &str = temp.to_str();
And now you later code that uses filename
just works. You may be wondering why writing the temporary variable makes a difference. The answer is that temporaries created by the compiler are destroyed at the end of the sentence that contains it.
Note that the filename
is actually a reference, so it must have an associated lifetime, which is, obviously1, that of variable temp
. That means that filename
cannot outlive temp
. But in your code, temp
is not actually a named variable but a temporary that gets destroyed as soon as the line completes, and filename
is rendered unusable.
If you read the full compiler error, you'll see a:
note: consider using a
let
binding to create a longer lived value.
which suggest exactly this.
[1]: Obvious if you read the definition of the function of PathBuf
: fn to_str<'a>(&'a self) -> Option<&'a str>
(adding the elided lifetime for clarity).
Upvotes: 2