我有以下代码:
struct Callable<P> {
callable: Box<FnMut(&P)>,
}
struct Parameters<'a> {
text: &'a str,
}
struct Context<'a> {
call: Callable<Parameters<'a>>,
}
Callable
是可以通过引用类型参数来调用的东西P
。
Parameters
包含对字符串的引用,所以它有一个通用的生命周期参数是完全合理的。它基本上是说该text
领域应该至少与Parameters
它本身一样长。
我也必须为它添加一个通用的生命周期参数Context
,否则我不能用于call
成员类型。这对我来说没有任何意义,因为该'a
参数与Context
.
我怀疑该for <'a>
构造可以以某种方式使用,我只是不知道把它放在哪里。
for<'a>
只能用于 trait bounds 和 trait 对象;Parameters<'a>
不是特征。
解决方案是目前正在开发的一个特性:泛型关联类型。泛型关联类型可以被认为是对类型进行操作的函数(即给定一个或多个类型/生命周期,产生另一种类型)。你的程序看起来像这样:
#![feature(generic_associated_types)]
trait CallableParameterFamily {
type Type<'a>;
}
struct Callable<P>
where
P: CallableParameterFamily,
{
callable: Box<for<'a> FnMut(&P::Type<'a>)>,
}
struct Parameters<'a> {
text: &'a str,
}
enum ParametersFamily {}
impl CallableParameterFamily for ParametersFamily {
type Type<'a> = Parameters<'a>; // given 'a, produce Parameters<'a>
}
struct Context {
call: Callable<ParametersFamily>,
}
(从 Rust 1.25.0-nightly (2018-02-14 3ec5a99aaa0084d97a9e845b34fdf03d1462c475
) 开始,该功能似乎已部分实现,上面的代码不起作用,所以我无法验证它是否正确或者我是否在这里犯了错误.)
这里的关键是我们不想要Callable<Parameters<'a>>
具有特定生命周期的'a
,因为我们可能希望'a
每次调用具有不同生命周期的闭包。我们不能将类型构造函数(例如Parameters
)作为类型参数传递给泛型类型(例如P
on Callable
)。
泛型关联类型将允许以间接方式实现这一点:我们必须定义具有泛型关联类型(此处CallableParameterFamily
为 GAT Type
)的特征以及实现该特征的类型(此处为ParametersFamily
)。请注意,ParametersFamily
它没有生命周期参数。然后我们将Callable<ParametersFamily>
其用作 中call
字段的类型Context
;Context
不再需要生命周期参数。然后,在 中Callable
,不是P
直接使用,而是P::Type<'a>
在引入'a
using后使用for<'a>
。当实例化为 时Callable<ParametersFamily>
,P::Type<'a>
将扩展为Parameters<'a>
,这正是我们想要的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句