2

基本的に、次のようなマクロがあります。

macro_rules! my_macro {
  ( $expr:expr; $( $pat:pat ),* ) => {
    match $expr {
      $(
        $pat => $(some-macro-magic-here),
      )*
    }
  }
}

$(some-macro-magic-here)に入ることができるものはありますか?

my_macro!(foo; A, B, C)

に拡大します

match foo {
  A => 2,
  B => 4,
  C => 6,
}

?

マクロの一連の入力を効果的に「列挙」できる同様の機能を取得できる他の方法はありますか?

同様の効果を得るためにおそらく再帰マクロを書くことができると思いますが、私が考えているよりもエレガントで慣用的な方法があるかどうか疑問に思っています

4

2 に答える 2

1

Rust はマクロ経由でブランチをmatch作成することを許可していないため、このようなステートメントを作成することはできません。別名、これは現在機能しません。match

match val {
    my_macro! (A, B, C)
}

if letただし、この場合、ネストされたブロックと再帰マクロを使用して「ハック」できます。

macro_rules! my_macro {
  ($expr:expr; $($pat:pat),*) => {
    my_macro!($expr; 2, 2; $($pat),*)
  };
  ($expr:expr; $curr:expr, $step:literal; $pat:pat) => {
    if let $pat = $expr {
        $curr
    } else {
        unreachable!()
    }
  };
  ($expr:expr; $curr:expr, $step:literal; $pat:pat, $($rest:pat),*) => {
    if let $pat = $expr {
        $curr
    } else {
        my_macro! ($expr; $curr+$step, $step; $($rest),*)
    }
  }
}

遊び場

2期待される定数を作成するのに十分な量が追加されたネストされたエントリが生成されます。あるいは、それを乗算に置き換えることもできますが、とにかくコンパイラによって最適化される必要があります。

于 2019-12-25T16:39:06.310 に答える