初心者&未来の自分へ
宣言マクロは全然構文が違うし、なんだか難しそうですよね。
少し書いてたら慣れたので、コツを書いておこうと思います。
$( ),* と書いて、繰り返しと読む
引数定義でも、出力定義でも、$( ),*は、中に定義された変数(とパターン)を繰り返すものです。これを打つときは
「 $ 」->く
「 ( 」->り
「 ) 」->か
「 , 」->え
「 * 」->し
と声に出すくらいでもいいと思います。
なお、コンマは必須ではないですが細かいことは書きません。
色んな呼び出し方ができる
マクロの呼び出し引数は、色んな呼び出し方を定義できます。
これは今回実装したコードで、入力された数列を複製して二重ループ(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と展開されます。これだけ覚えてりゃある程度読めます。
終わり
続きがあったら書きます。