0

fn a() {}似乎满足了预期 a 的解析规则fn,然后是其他一些东西。items 应该可以是函数定义,对吧?所以他们应该工作,对吧?

macro_rules! multi_impl {
    (for $base:ty :
        $($t:ty {
            $($i:item);*
        }),+) =>
    {
        $(
            impl $t for $base
            {
                $( $i )*
            }
        )+
    }
}

trait A {
    fn a();
}

trait B {
    fn b();
}

struct S;

multi_impl! {
    for S:
    A {
        fn a() {}
    }, B {
        fn b() {}
    }
}

fn main() {
    S::a();
    S::b();
}

操场

有问题的错误:

error: expected one of `const`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `fn a() { }`
  --> <anon>:11:20
   |
11 |                 $( $i )*
   |                    ^^

使它$( fn $i)*只会更改错误以抱怨在 之后需要一个标识符fn,这是有道理的,但最初的错误没有(至少对我而言)。

解析器对源代码中的代码与宏放入源代码中的代码有区别吗?

4

1 回答 1

3

问题不在于 afn不是项目,而在于 a 的主体impl 包含项目。它包含“impl items”。它抱怨的是您试图将方形块放入圆孔中,而不是块的颜色错误。

是的,这是两个不同的东西。不,您不能在宏中捕获“impl items”。不,你不能将一个项目变成一个 impl 项目。因为宏捕获 AST 节点,而不是令牌。好吧,方法可以有一个self参数,而常规函数没有。我不知道,大概在当时这似乎是个好主意。

把假设的来回放在一边,在这种情况下的解决方案是不要费心去尝试匹配任何特别的东西,而只是匹配任何东西

macro_rules! multi_impl
{
    (for $base:ty :
        $($t:ty {
            $($body:tt)*
        }),+) =>
    {
        $(
            impl $t for $base
            {
                $($body)*
            }
        )+
    }
}
于 2017-06-08T03:49:33.167 回答