macros - 如何匹配宏中的方法?

标签 macros rust

item 片段可以匹配函数,但是如果函数的第一个参数是 self 的变体, 如果它是方法,它不被识别为 item:

macro_rules! test {
    ( $fn:item ) => {}
}

// Ok
test! {
    fn foo() -> bool {
        true
    }
}

// Not ok
test! {
    fn foo(self) -> bool {
        true
    }
}

fn main() {}

如何匹配方法?

最佳答案

采用self 的函数不是项,因为如果没有impl block 来为self 提供类型,它就不可能存在于顶层

虽然周围的 impl block 是一个项目。

要匹配功能,您必须将其分解,可能像这样:

macro_rules! test {
    ( fn $fn:ident ( self ) -> $ret:ty $body:block ) => {};
}

但是你必须在 impl block 中使用 宏:

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
    ) => {};
}

而且这些甚至不考虑生命周期或类型参数。

通过将这些情况委托(delegate)给另一个宏来重用代码可能会很棘手,因为您在宏中没有 self 类型,因此您可能无法摆脱不幸的是重复。

关于macros - 如何匹配宏中的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51571774/

相关文章:

c++ - QT_NO_DEBUG 是否会导致 NDEBUG 的定义?

macros - Clojure 嵌套宏

c++ - GCC 中的宏有效但在 Solaris 中编译器失败?

rust - Rust,在闭包内创建一个闭包,避免 “closure may outlive the current function”

rust - 如何检测是否为声明性宏提供了可选关键字?

rust - 如何允许为 Args 值调用 `last`?

c - 如何将字符串作为参数传递给 C 宏

c - 奇怪的宏观行为

rust - 格式所需的类型注释!解析 postgres 结果时

sockets - Rust 中的套接字服务器不接收