2
votes

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.

1
I just ran the code in the link you provided and it throws an error. What did you do to make it run? - Jarred Parr
Sorry, my bad, I messed up with your code, let me explain below in a minute... - rodrigo

1 Answers

2
votes

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).