2017-07-15 19 views
0

2つの式と識別子に一致するマクロを作成しています。私はそれが必要でない場合、識別子を無視することができるようにしたいと思いますが、私は_を使用すると、コンパイラは文句を言うようです。マクロでidentの代わりにアンダースコアを一致させる

マイマクロ:私が何をしたいのですがどのような

macro_rules! if_some { 
    ($x:expr, $id:ident, $expr:expr) => { 
     match $x { 
      None => None, 
      Some($id) => Some($expr), 
     } 
    }; 
} 

if_some!(obtain_an_option(), x, do_something_with(x)) 

if_some!(obtain_an_option(), _, do_something()) 

2回目の呼び出しが失敗しました。

私は識別子を受け取っていない2番目のマクロif_some_!を定義していました(2番目のパターンも使用できませんでした)。私はここで、識別子またはちょうど_を受け入れる」と言うする方法はありだと確信しています。

は、たぶん、すでにこのためのマクロ/機能(のようなOption::mapが、今私はそれについて考える)...それにもかかわらず、それがいいと思いますがあります今

答えて

3

Option::map最高solutのようですこの特定の問題のためのイオンがありますが、実際にはidentと_の両方をパターンとして期待するマクロが必要な場合は、$p:patフラグメントを使用することもできます。断片は(ref x, y)のようなより広い範囲のパターンを受け入れますが、これは通常受け入れられます。

macro_rules! if_some { 
    ($x:expr, $p:pat, $expr:expr) => { 
     match $x { 
      None => None, 
      Some($p) => Some($expr), 
     } 
    }; 
} 

fn main() { 
    println!("{:?}", if_some!(Some(12), x, x + 1)); // Some(13) 
    println!("{:?}", if_some!(Some(12), _, 1)); // Some(1) 
} 
5

最も簡単な方法は、アンダースコアに一致する第二のアームを追加することです:。。

macro_rules! if_some { 
    ($x:expr, _, $expr:expr) => { 
     match $x { 
      None => None, 
      Some(_) => Some($expr), 
     } 
    }; 

    ($x:expr, $id:ident, $expr:expr) => { 
     match $x { 
      None => None, 
      Some($id) => Some($expr), 
     } 
    }; 
} 

をそして、あなただけのOption::mapをしたいようにはい、これが聞こえる

関連する問題