Rust 中另一个宏规则定义的内部宏规则中是否可以有重复?

问题描述 投票:0回答:1

我想编写一个宏来定义带有属性的枚举的宏,如下所示:

macro_rules! define_enum_definer {
  {
    $($variant: ident => $t: ty,)+
  }
  => {
    macro_rules! define_enum {
      ($(#[$attrs:meta])*$name: ident($container: ident)) => {
        $(#[$attrs])*
        enum $name {
          $($variant($container<$t>),)+
        }
      };
    }
  };
}

define_enum_definer! { I32 => i32, I64 => i64, }
define_enum!(
  #[derive(Clone, Debug)]
  #[non_exhaustive]
  DynTypedVec(Vec)
);

fn main() {
  let x = DynTypedVec::I32(vec![1, 2, 3]);
  println!("{:?}", x);
}

但这失败了

error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
  --> src/main.rs:12:9
   |
12 |       ($(#[$attrs:meta])*$name: ident($container: ident)) => {
   |         ^^^^^^^^^^^^^^^^

它试图在外部宏中重复语法变量,但我需要它对内部宏重复。我试图用

$dollar
来逃避内部重复,但这也失败了

error: missing fragment specifier
  --> src/main.rs:12:8
   |
12 |       ($dollar(#[$attrs:meta])*$name: ident($container: ident)) => {
   |        ^^^^^^^
...
22 | define_inner_macro! { Foo => i32, Bar => i64, }
   | ----------------------------------------------- in this macro invocation

有没有办法解决这个问题,或者是我使用程序宏的唯一办法?

rust macros
1个回答
0
投票

没那么复杂,你必须通过将其加倍来转义仅在内部宏中的每个

$

#![feature(macro_metavar_expr)]
macro_rules! define_enum_definer {
  {
    $($variant: ident => $t: ty,)+
  }
  => {
    macro_rules! define_enum {
      ($$(#[$$attrs:meta])* $$name:ident ( $$container:ident )) => {
        $$(#[$$attrs])*
        enum $$name {
          $($variant($$container<$t>),)+
        }
      };
    }
  };
}
© www.soinside.com 2019 - 2024. All rights reserved.