2017-11-30 16 views
0

私のコードには、Option<T>の構造体がたくさんあります。私は多くの場所でそれらと一緒に作業する必要があるので、私のコードはcar.engine.as_ref().unwrap()のような構造体アクセスで散らばっています。これはコードを読みやすくするための痛みです。as_ref()。unwrap()のショートカットはありますか?

同じことをOption<T>タイプのデフォルトの機能はありますか? car.engine.get()のように?もちろん、すべての構造体メンバのアクセサー関数を書くことができますが、これは基本的なもののための過度のようです。私はそれを間違っているのですか?

マクロについてよくわかりませんが、マクロで短縮する方法はありますか? unwrap以来

答えて

5

あなたはを利用することができるかもしれない:

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

そうでない場合、あなたは簡単に拡張特性に独自の機能のおかげで書くことができます(錆1.22以降)(それはResult<T, E>でないような)もOption<T>タイプで動作します?オペレータ:

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) 
    } 
} 
+0

実際、その機能は既に利用可能です(https://blog.rust-lang.org/2017/11/22/Rust-1.22.html)。 –

+0

@ E_net4ありがとう、修正済み。 – ljedrz

+0

これは他の答えよりも慣れているようですので、私はこれを確認します。両方の答えは本当に良いです。 – itmuckel

4

私は驚くべきことではないというようなものを、見つけることができませんが、一般的にとにかくお勧めしません。エラーケースを処理したい場合は、この操作を行うことができます。

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(); 
+0

非常に貴重な情報。私はあなたがデフォルトのタイプを拡張できることを知らなかった。 – itmuckel

関連する問題