我已经将我在this snippet中看到的一个问题归结为:
macro_rules! test_impl {
(&mut $_:ty) => { 1 };
(&$_:ty) => { 2 };
($_:ty) => { 3 };
}
macro_rules! test {
($val: literal, $($t:ty), *) => { ($val $(, test_impl!($t))*) }
}
fn main() {
// I'm expecting (0, 3, 2, 1) here...
println!("{:?}", test!(0, f64, &f64, &mut f64));
}
当结束打印输出时:
(0, 3, 3, 3)
看起来t
类型的引用和可变部分没有被传递。我是否理解了这是如何工作的错误?有没有办法通过外部test!
宏传递“reference/mut-ness”,并在test_impl!
中匹配它?
1条答案
按热度按时间wi3ka0sx1#
是的。引用参考文献:
当将匹配的片段转发到另一个宏时,第二个宏中的匹配器将看到片段类型的不透明AST。第二个宏不能使用文字标记来匹配匹配器中的片段,只能使用相同类型的片段说明符。
ident
、lifetime
和tt
片段类型是一个例外,它们可以通过文字标记来匹配。您无法使用宣告式宏来解决这个问题:proc宏可以删除那些不可见的片段(它们被表示为groups,带有不可见的分隔符),但
macro_rules!
不能。唯一的方法是不从一开始就捕获它们,而是将它们与tt
匹配。匹配复杂的片段(如ty
)可能很难,需要tt munching。