宏中的令牌树(处理参数列表)

时间:2014-10-13 19:40:23

标签: macros rust

目前,将扩展方法添加到另一个模块中的类型(即使此模块位于子模块中)的唯一方法是定义新特征并为该类型实现它。然而,这非常笨拙,因为方法的数量变得很大:

trait Ops {
    fn parse_list_item(&self, current_item: ListItemInfo) 
        -> ParseResult<(Document, ListItemInfo)>;
    fn parse_list_item_content(&self) -> ParseResult<Document>;
}

impl<'a> Ops for MarkdownParser<'a> {
    fn parse_list_item(&self, current_item: ListItemInfo) 
            -> ParseResult<(Document, ListItemInfo)> {
        // ...
    }

    fn parse_list_item_content(&self) -> ParseResult<Document> {
        // ...
    }
}

您必须两次编写方法签名。如果更改,您还必须在多个位置更新它。它还会增加很多噪音。

我虽然这些宏会有所帮助,但我不知道如何为函数中的参数列表编写正确的macro_rules!模式。以下是我到目前为止的情况:

#![feature(macro_rules)]

struct Foo;

macro_rules! ops (
    ($(fn $name:ident($($args:tt)*) -> $ret:ty $body:block)+) => (
        trait Ops {
            $(fn $name($($args)*) -> $ret;)+
        }

        impl Ops for Foo {
            $(fn $name($($args)*) -> $ret $body)+
        }
    )
)

mod ops {
    ops! {
        fn method1(&self) -> int {
            10
        }

        fn method2(&self, i: int) -> () {
            println!("{}", i + self.method1());
        }
    }

    pub fn run_test() {
        Foo.method2(22);
    }
}

fn main() {
    ops::run_test();
}

它以相当令人讨厌的信息失败了:

/tmp/rs/ops/src/main.rs:8:27: 8:31 error: expected type, found token INTERPOLATED(NtTT(ptr::P<ast::TokenTree>{ptr: box TTTok(codemap::Span{lo: codemap::BytePos(337u32), hi: codemap::BytePos(338u32), expn_id: codemap::ExpnId(4294967295u32)}, BINOP(AND))}))
/tmp/rs/ops/src/main.rs:8             $(fn $name($($args)*) -> $ret;)+
                                                    ^~~~

它可能值得一个bug报告,因为错误信息非常令人生畏,但是,我没有看到另一种传递参数的方法。它似乎与this issue有关,但是,我希望有一种解决方法 in this case

有什么建议吗?

0 个答案:

没有答案