rust - 尝试在宏扩展中实现特征时出现宏错误

标签 rust rust-macros

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

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();
}

playground

有问题的错误:

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

制作它$( fn $i)* 只会改变错误来提示在 fn 之后需要一个标识符,这是有道理的,但最初的错误并没有(至少对我而言)。

对于源代码中的代码与通过宏放入源代码中的代码,解析器是否存在差异?

最佳答案

问题不在于 fn 不是项目,而是 impl 的主体 包含项目。它包含“实现项目”。它提示的是你试图将方形 block 放入圆孔中,而不是 block 颜色错误。

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

抛开假设的来回,这种情况下的解决方案是不要费心尝试匹配特定中的任何内容,而只匹配任何内容

macro_rules! multi_impl
{
    (for $base:ty :
        $($t:ty {
            $($body:tt)*
        }),+) =>
    {
        $(
            impl $t for $base
            {
                $($body)*
            }
        )+
    }
}

关于rust - 尝试在宏扩展中实现特征时出现宏错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44426175/

相关文章:

rust - 如何在 Rust FFI 中发布常量字符串?

rust - 为什么 Vec<T> 期望 &T 作为 binary_search 的参数?

rust - 创建一个无法在其 crate 之外实例化的零大小结构的惯用方法是什么?

macros - 是否可以在一个箱子中同时包含程序宏和逻辑?

rust - 实现 proc 宏时的循环包依赖

rust - 如何从actix SyncContext向另一个参与者发送消息?

rust - 如何将两个 HashSet 相交,同时将共同的值移动到一个新集合中?

rust - 在 macro_rules 中存储状态

rust - 是否可以扩展单个宏而不是整个文件?

rust - 我可以使用 Rust 的宏重复检测表达式是否为可变变量吗?