我有以下代码:
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>
构造可以以某种方式使用,我只是无法弄清楚它放在哪里。
答案 0 :(得分:1)
for<'a>
只能用于特征边界和特征对象; 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
),该功能似乎已部分实施,上述代码无效,因此我可以&#39; t验证它是否正确或我是否在这里犯了错误。)
这里的关键是我们不希望Callable<Parameters<'a>>
具有特定的生命周期'a
,因为我们可能希望每次为'a
调用不同生命周期的闭包。我们无法将类型构造函数(例如Parameters
)作为类型参数传递给泛型类型(例如P
上的Callable
)。
通用关联类型将以间接方式允许:我们必须定义具有通用关联类型的特征(此处为CallableParameterFamily
与GAT Type
)以及实现该类型的类型特质(这里,ParametersFamily
)。请注意ParametersFamily
没有生命周期参数。然后,我们使用Callable<ParametersFamily>
作为call
中Context
字段的类型; Context
不再需要生命周期参数。然后,在Callable
中,我们使用P
引入P::Type<'a>
,而不是直接使用'a
,而是使用for<'a>
。当实例化为Callable<ParametersFamily>
时,P::Type<'a>
将扩展为Parameters<'a>
,这就是我们想要的。