如何提供可选泛型作为 macro_rules 参数?

How do I provide optional generics as macro_rules arguments?

我想使用 macro_rules 为特征创建一个实现。类型应作为宏参数给出。但是,其中一些类型可能包含生命周期,所以我需要它们。我还有一个来自宏内部的泛型类型。结果应该看起来像

impl<T> Foo<T> for MyType { .. }
// Or with lifetime:
impl<'a, 'b, T> Foo<T> for LifetimeType<'a, 'b> { .. }

如何构造宏以及如何调用它?

您可以使用 lifetime 说明符来匹配宏参数中的生命周期:

trait Foo{}

macro_rules!impl_foo {
    ($($l:lifetime),*; $t:tt) => { impl<$($l),*> Foo for $t<$($l),*> {} };
    ($t:ty) => { impl Foo for $t {} };
}

并这样称呼它:

impl_foo!(A);
impl_foo!('a, 'b; B);

Playground

请注意,我能找到的唯一提到捕获的 lifetime 说明符的地方是 the associated RFC. It is in particular conspicuously missing from The little book of Rust macros,即使它在 2016 年合并了......