我想编写一个宏来定义带有属性的枚举的宏,如下所示:
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
有没有办法解决这个问题,或者是我使用程序宏的唯一办法?
没那么复杂,你必须通过将其加倍来转义仅在内部宏中的每个
$
:
#![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>),)+
}
};
}
};
}