我在结构中的FnMut字段的参数的生命周期中使用了什么?

时间:2018-02-17 06:05:41

标签: rust

我有以下代码:

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>构造可以以某种方式使用,我只是无法弄清楚它放在哪里。

1 个答案:

答案 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>作为callContext字段的类型; Context不再需要生命周期参数。然后,在Callable中,我们使用P引入P::Type<'a>,而不是直接使用'a,而是使用for<'a>。当实例化为Callable<ParametersFamily>时,P::Type<'a>将扩展为Parameters<'a>,这就是我们想要的。