I have a String unformatted and an Optional formatted stored in a struct. I want to get a &str to either the optional if it's some or the other String without copying anything. Here is the current code that works:
let line: &str = match &self.formatted {
Some(formatted) => formatted,
None => &self.unformatted,
};
This syntax seems overly verbose, but I haven't found another easier way to do it (e.g. with unwrap_or or similar). Any suggestions on how to turn this into a one-liner? Thanks!
The difference is that as_deref will return Option<&str> while as_ref returns Option<&String> at first (which later gets coerced into Option<&str>where the &String later gets coerced to &str).
as_deref would fail if the option stores some other type (e.g. other than a String) that is !Deref. On the other hand, as_ref might result in a &String when type inference doesn't enforce coercion.
I slightly lean towards Option::as_ref though and would let the coercion happen later.
On the other hand, Option::as_ref won't work here, for example:
pub struct S {
unformatted: &'static str,
formatted: Option<String>,
}
impl S {
pub fn foo(&self) -> &str {
//self.formatted.as_ref().unwrap_or(&self.unformatted) // fails to compile
self.formatted.as_deref().unwrap_or(&self.unformatted)
}
}
I have to say though, that @H2CO3 has a valid point:
It's at least arguable if
let line = self.formatted.as_deref().unwrap_or(&self.unformatted);
is really easier to read than:
let line: &str = match &self.formatted {
Some(formatted) => formatted,
None => &self.unformatted,
};
The former is short and concise but requires the reader to be more aware of the involved types. The latter may be more self-explaining to a reader who is skimming through the program.
In this particular case, I think the combinator version's conciseness is valuable, but when longer and/or more complex computations are involved, I tend to begin to lean towards the match, because I don't want to hide the complexity too much.
In either case, I don't have a very strong opinion (other than match not being a big burden to read); for example, I see "always use combinators when you can for consistency" as an equally valid argument.