0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rustで宣言マクロを書いて得た、個人的なコツ

0
Posted at

初心者&未来の自分へ

宣言マクロは全然構文が違うし、なんだか難しそうですよね。
少し書いてたら慣れたので、コツを書いておこうと思います。

$( ),* と書いて、繰り返しと読む

引数定義でも、出力定義でも、$( ),*は、中に定義された変数(とパターン)を繰り返すものです。これを打つときは
「 $ 」->く
「 ( 」->り
「 ) 」->か
「 , 」->え
「 * 」->し
と声に出すくらいでもいいと思います。
なお、コンマは必須ではないですが細かいことは書きません。

色んな呼び出し方ができる

マクロの呼び出し引数は、色んな呼び出し方を定義できます。

これは今回実装したコードで、入力された数列を複製して二重ループ(pickloop)に渡しています。

引数に特定の処理を表す文字列を要求することで、名前空間を汚染することなく複数の内部マクロを定義できます。

macro_rules! impl_bitvalue {
    (pickloop | $($all:literal),*)=>{};
    (pickloop $pickup:literal $(,$waiting:literal)* | $($all:literal),*)=>{
        impl_bitvalue!(pick $pickup from $($all),*);
        impl_bitvalue!(pickloop $($waiting),* | $($all),*);
    };
    (pick $pickup:literal from $($array:literal),* $(,)?) => {
        paste!{
            impl<$([<B $array>]:Bit),*> BitValue<$pickup> for ($([<B $array>]),*){
                type Value = [<B $pickup>];
            }
        }
    };
    ($end:literal)=>{
        paste!{
            impl<[<B $end>]:Bit> BitValue<$end> for [<B $end>]{
                type Value = [<B $end>];
            }
        }
    };
    ($head:literal,$($tail:literal),* $(,)?) => {
        impl_bitvalue!(pickloop $head,$($tail),* | $head,$($tail),*);
        impl_bitvalue!($($tail),*);
    };
}

pasteはとりあえず[<Some $num>]を覚える

[<Some $num>]って書いたら、$numが0ならSome0と展開されます。これだけ覚えてりゃある程度読めます。

終わり

続きがあったら書きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?