Rust宏接受类型与通用参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust宏接受类型与通用参数相关的知识,希望对你有一定的参考价值。
我有一个实现特征的宏,impl_Trait!()
。现在,它适用于没有泛型参数的类型,但我不确定如何将类型参数添加到impl
关键字。
macro_rules! impl_FooTrait {
($name:ty) => {
impl $crate::FooTrait for $name { ... }
};
}
struct Bar(i32);
impl_FooTrait!(Bar);
// All OK
struct Baz<'a>(&'a i32);
impl_FooTrait!(Baz<'a>);
// use of undeclared lifetime name `'a`
答案
以免责声明的方式提交此答案:可能有更好的方法来做到这一点。我还不熟悉宏观的土地。
你可以使用tt
(单一标记)标识符来接受你想要的另一个宏臂(playground link)
macro_rules! impl_FooTrait {
($name:ty, $lifetime:tt) => {
impl<$lifetime> $crate::FooTrait for $name { }
};
($name:ty) => {
impl $crate::FooTrait for $name { }
};
}
struct Bar(i32);
impl_FooTrait!(Bar);
struct Baz<'a>(&'a i32);
impl_FooTrait!(Baz<'a>, 'a); // Use and declare the lifetime during macro invocation
看起来我觉得有点奇怪。我有兴趣看到任何其他有替代品的答案。
这是一个实际实现的例子:Playground link
另一答案
这是一个老问题,但似乎在这里似乎没有一个好的答案。我有一个部分解决方案,虽然它匹配一些不正确的输入,我不能让它适用于生命周期参数。
#[macro_export]
macro_rules! impl_trait {
// this evil monstrosity matches <A, B: T, C: S+T>
// but because there is no "zero or one" rule, also <D: S: T>
($ty:ident < $( $N:ident $(: $b0:ident $(+$b:ident)* )* ),* >) =>
{
impl< $( $N $(: $b0 $(+$b)* )* ),* >
$crate::path::to::Trait
for $ty< $( $N ),* >
{
// function implementations go here
}
};
// match when no type parameters are present
($ty:ident) => {
impl_trait!($ty<>);
};
}
以上是关于Rust宏接受类型与通用参数的主要内容,如果未能解决你的问题,请参考以下文章
打字稿:如何制作接受对象的类型,其键匹配通用但所有值都是值参数的映射函数