let mut v = Vec::<&str>::new();
let opt = Some("foo".to_string());
if let Some(s) = opt {
v.push(s.as_str());
} // `s` dropped here while still borrowed
dbg!(v); // borrow later used here
As I understand it, the issue occurs because value I'm trying to put into the container has shorter lifetime than the container itself. So I can move it into the outer scope:
let unscopped;
if let Some(s) = opt {
unscopped = s;
v.push(unscopped.as_str());
}
dbg!(v);
It works, but it feels too verbose. What would be an ergonomic way of doing this?
if let Some(s) = opt.as_ref() {
v.push(s.as_str());
}
or match on &opt like this:
if let Some(s) = &opt {
v.push(s.as_str());
}
In more complicated cases, you might want to use the ref keyword to specify which bindings should be by-reference:
if let Some(ref s) = opt {
v.push(s.as_str());
}
For this specific case, you can also use Option::as_deref, which combines the as_ref and as_str operations, converting &Option<String> into Option<&str> in a single call: