1个版本 (0个不稳定版)
1.0.0-alpha | 2020年2月9日 |
---|
#1449 在 过程宏
11KB
177 代码行
impl-template
impl-template
是一个Rust编程语言的过程宏,允许你定义“impl”项的模板,并根据配置将其展开为多个实例。
从某种意义上讲,如果你事先知道所有要实现的类型,那么它就像是编译时的泛型 impl。
用法
trait Foo {}
struct Bar;
struct Baz;
#[impl_template]
impl Foo for ((Bar, Baz)) {
}
这将生成以下代码
impl Foo for Bar {
}
impl Foo for Baz {
}
高级用法
impl-template
会寻找双元组的模式。这些是语法上有效的Rust代码,但据我所知,相当无用,因此不应该在日常Rust代码中出现。
多个双元组模式
你可以拥有任意数量的这些双元组。 impl-template
会将这些双元组创建成笛卡尔积,并据此生成相应的 impl-blocks。
trait GenericFoo<T, S> { }
struct Bar;
struct Baz;
struct One;
struct Two;
struct Three;
struct Alpha;
struct Beta;
#[impl_template]
impl GenericFoo<((Bar, Baz)), ((Alpha, Beta))> for ((One, Two, Three)) { }
上面的片段将展开为12个 impl blocks (2 * 3 * 2)。
引用类型
impl-template
允许你在模板块中引用类型。它会为方案中的每个双元组生成一个假标识符 __TYPE{}__
,其中 {}
被替换为基于0的索引。
我们可以扩展 GenericFoo
,在其中我们需要命名类型参数的方法
trait GenericFoo<T, S> {
fn my_fn(arg1: T, arg2: S) -> Self;
}
struct Bar;
struct Baz;
struct One;
struct Two;
struct Three;
struct Alpha;
struct Beta;
#[impl_template]
impl GenericFoo<((Bar, Baz)), ((Alpha, Beta))> for ((One, Two, Three)) {
fn my_fn(_arg1: __TYPE0__, _arg2: __TYPE1__) -> __TYPE2__ {
unimplemented!()
}
}
上面的代码展开为以下(非穷尽列表)
impl GenericFoo<Bar, Alpha> for One {
fn my_fn(_arg1: Bar, _arg2: Alpha) -> One {
unimplemented!()
}
}
impl GenericFoo<Bar, Beta> for One {
fn my_fn(_arg1: Bar, _arg2: Beta) -> One {
unimplemented!()
}
}
换句话说,__TYPE0__
是第一个双元组 ((Bar, Baz))
的类似迭代器的占位符,__TYPE1__
用于第二个,等等。
依赖关系
~2MB
~43K SLoC