是否有as_ref().unwrap()的快捷方式?

itm*_*kel 3 readability optional rust

在我的代码中,我有很多带有Option<T>s 的结构.我需要在很多地方使用它们,所以我的代码充满了类似的结构访问car.engine.as_ref().unwrap().这对代码可读性来说很痛苦.

Option<T>类型的默认函数是否相同?喜欢car.engine.get()?当然,我可以为每个结构成员编写访问器函数,但这对于一些非常基本的东西来说似乎有些过分.我做错了吗?

我不太了解宏,但是有没有办法用宏缩短它?

lje*_*drz 6

您可能能够利用?运算符(因为Rust 1.22)也适用于该Option<T>类型(就像它一样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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*edl 5

我找不到这样的东西,这并不奇怪,因为unwrap无论如何通常都会气馁.如果要处理错误情况,可以执行以下操作:

if let Some(ref e) = car.engine { println!("foo {}", e.serial); }
else { println!("nope"); }
Run Code Online (Sandbox Code Playgroud)

否则,由于扩展特性,您可以轻松编写自己的函数:

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();
Run Code Online (Sandbox Code Playgroud)

  • 非常有价值的信息。我不知道您可以扩展默认类型。 (2认同)