是否可以只使用 `macro_rules!` 来实现这个宏?
Is it possible to implement this macro using only `macro_rules!`?
我正在尝试创建一个宏,让我遍历类型列表以减少 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
有办法解决这个问题吗?我能否以某种方式生成一个随机标识符来代替 Ty
,以便在不使用 proc 宏或依赖项的情况下进行编译?
您可以在 const
声明中确定特征实现的范围。这样您就可以重复使用 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 {}
}
}
我正在尝试创建一个宏,让我遍历类型列表以减少 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
有办法解决这个问题吗?我能否以某种方式生成一个随机标识符来代替 Ty
,以便在不使用 proc 宏或依赖项的情况下进行编译?
您可以在 const
声明中确定特征实现的范围。这样您就可以重复使用 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 {}
}
}