Jarred Parr
Jarred Parr

Reputation: 1257

How to convert Option<&str> into &str?

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

Answers (1)

rodrigo
rodrigo

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

Related Questions