item
片段可以匹配函数,但是如果函数的第一个参数是self
的变体,则 ie (如果它是方法),则无法识别作为item
:
macro_rules! test {
( $fn:item ) => {}
}
// Ok
test! {
fn foo() -> bool {
true
}
}
// Not ok
test! {
fn foo(self) -> bool {
true
}
}
fn main() {}
如何匹配方法?
答案 0 :(得分:4)
采用self
的函数不是项,因为没有impl
块才能为self
提供类型,它就不能存在于顶层。
周围的impl
块 是一个项目。
要匹配该功能,您必须将其分解,也许像这样:
macro_rules! test {
( fn $fn:ident ( self ) -> $ret:ty $body:block ) => {};
}
但是您必须在impl
块内部使用宏 :
impl Foo {
test! {
fn foo(self) -> bool {
true
}
}
}
尽管如此,您还必须在这里处理很多可能的函数排列,最终可能会变得非常重复:
// enables the ? operator for optional parts
#![feature(macro_at_most_once_rep)]
macro_rules! test {
( fn $fn:ident ( $($name:ident : $type:ty),* ) $( -> $ret:ty )?
$body:block
) => {};
( fn $fn:ident ( self $(, $name:ident : $type:ty)* ) $( -> $ret:ty )?
$body:block
) => {};
( fn $fn:ident ( &self $(, $name:ident : $type:ty)* ) $( -> $ret:ty )?
$body:block
) => {};
( fn $fn:ident ( &mut self $(, $name:ident : $type:ty)* ) $( -> $ret:ty )?
$body:block
) => {};
}
这些甚至都没有考虑生存期或类型参数。
通过将这些情况委托给另一个宏来获得代码重用可能很棘手,因为您在宏内没有self
类型,因此很遗憾,您可能无法摆脱重复