rust - 是否可以只使用 `macro_rules!` 来实现这个宏?

标签 rust rust-macros

我正在尝试制作一个宏,让我遍历类型列表以减少 trait impl 样板。 (我目前正在使用不同的基于宏的解决方案,但如果不添加依赖项可能的话,这似乎更具可读性。)

这是我的目标语法:

trait MyTrait {}

tfor! {
    for Ty in [i32, u32] {
        impl MyTrait for Ty {}
    }
}

我的尝试:

macro_rules! tfor {
    (for $ty:ident in [$($typ:ident),*] $tt:tt) => {
        $(
            type $ty = $typ;
            tfor! { @extract $tt }
        )*
    };
    (@extract { $($tt:tt)* }) => {
        $($tt)*
    };
}

这会产生错误,因为两次迭代都在同一范围内定义了一个名为 Ty 的类型:

   |
4  |               type $ty = $typ;
   |               ^^^^^^^^^^^^^^^^
   |               |
   |               `Ty` redefined here
   |               previous definition of the type `Ty` here

Playground

有解决办法吗?我能否以某种方式生成一个随机标识符来代替 Ty,以便在不使用 proc 宏或依赖项的情况下进行编译?

最佳答案

您可以在 const 声明中确定 trait 实现的范围。这样您就可以重复使用 Ty 名称而不会引起冲突。

macro_rules! tfor {
    (for $ty:ident in [$($typ:ident),*] $tt:tt) => {
        $(
            const _: () = {
                type $ty = $typ;
                tfor! { @extract $tt }
            };
        )*
    };
    (@extract { $($tt:tt)* }) => {
        $($tt)*
    };
}

trait MyTrait {}

tfor! {
    for Ty in [i32, u32] {
        impl MyTrait for Ty {}
    }
}

关于rust - 是否可以只使用 `macro_rules!` 来实现这个宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66842217/

相关文章:

rust - 我可以重写这个宏规则吗!宏以一种与 rustfmt 一起工作的方式?

rust - 如何使用一系列参数初始化结构

rust - 将结构与 Rust 中的缓存行对齐

rust - 在参数化函数中复制/克隆向量的惯用 Rust 方法是什么?

performance - 为什么我的 for 循环代码比迭代器慢?

rust - 如何处理或测试某个类型是否是 Rust 宏中的选项?

rust - 元组使用rust 的生命周期问题。

rust - Arcs 中的元组如何用引用解构?

rust - 如何从宏中的表达式参数中获取标识符?

rust - proc_macro_attribute 函数内部是否存在一致的编译上下文?