In my code I have a lot of structs with Option<T>
s in them. I need to work with them in a lot of places, so my code is littered with struct accesses like car.engine.as_ref().unwrap()
. This is pain for code readability.
Is there a default function on the Option<T>
type that does the same? Like car.engine.get()
? Of course I could write accessor functions for every struct member, but this seems like an overkill for something so basic. Am I doing it wrong?
I don't know much about macros, but is there a way to shorten it with macros?
You might be able to take advantage of the ?
operator that (since Rust 1.22) also works with the Option<T>
type (like it does with Result<T, E>
):
struct Foo;
struct Bar {
foo: Option<Foo>,
// other optional fields
}
impl Bar {
fn use_optional_fields(&self) -> Option<&Foo> {
let foo = self.foo.as_ref()?;
// use optional fields
Some(foo)
}
}
I can't find anything like that, which is not surprising, since unwrap
is generally discouraged anyway. If you want to handle the error case, you can do this:
if let Some(ref e) = car.engine { println!("foo {}", e.serial); }
else { println!("nope"); }
Otherwise, you can easily write your own function thanks to extension traits:
trait OptionExt {
type Value;
fn unwrap_ref(&self) -> &Self::Value;
fn unwrap_mut(&mut self) -> &mut Self::Value;
}
impl <T> OptionExt for Option<T> {
type Value = T;
fn unwrap_ref(&self) -> &T { self.as_ref().unwrap() }
fn unwrap_mut(&mut self) -> &mut T { self.as_mut().unwrap() }
}
// Now you can write
let e = car.engine.unwrap_ref();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With