鏽病本書有rather long chapter on macros,但重複的部分是例子有點害羞...
有幾種方法來處理宏可選參數。如果你有一個只能出現一次的可選參數,那麼你不應該使用重複:你應該不是在你的宏定義多種模式,如:
macro_rules! single_opt {
($mand_1:expr, $mand_2:expr) => {
single_opt!($mand_1, $mand_2, "Default")
};
($mand_1:expr, $mand_2:expr, $opt:expr) => {
println!("1. {} 2. {}, 3. {}", $mand_1, $mand_2, $opt)
};
}
fn main() {
single_opt!(4, 4);
}
如果你想允許的參數任意數量,那麼你需要重複。您的原始宏不起作用,因爲您將逗號放在重複之外,所以您必須調用該宏作爲single_opt!(4,4,);
。
如果你的論點,然後重複一個固定的數字,你可以把逗號重複內的第一個標記:
macro_rules! single_opt {
($mand_1:expr, $mand_2:expr $(, $opt:expr)*) => {
println!("1. {} 2. {}, 3. {}", $mand_1, $mand_2, $($opt),*)
};
}
但是,它並沒有在這種特殊情況下的工作:
<anon>:2:33: 2:47 error: `$mand_2:expr` is followed by a sequence repetition, which is not allowed for `expr` fragments
<anon>:2 ($mand_1:expr, $mand_2:expr $(, $opt:expr)*) => {
^~~~~~~~~~~~~~
所以我們得回去定義兩種模式:
macro_rules! single_opt {
($mand_1:expr, $mand_2:expr) => {
single_opt!($mand_1, $mand_2, "Default")
};
($mand_1:expr, $mand_2:expr, $($opt:expr),*) => {
{
println!("1. {} 2. {}", $mand_1, $mand_2);
$(
println!("opt. {}", $opt);
)*
}
};
}
fn main() {
single_opt!(4, 4, 1, 2);
}
一重複的形式爲$(PATTERN) SEPARATOR COUNT
,其中PATTERN
是要重複的模式,SEPARATOR
是分隔每次重複一個可選的令牌(在這裏,它是,
)和COUNT
是「零個或多個」要麼*
或+
爲「一個或多個發生」。
然後,在宏擴展中,我們需要一個重複塊才能訪問$opt
。語法完全相同,但請注意分隔符不必相同(這裏,擴展中沒有分隔符)。