如何指定具有生命周期参数的关联类型?

How do I specify an associated type with a lifetime parameter?

我有这个特征代表从模板呈现文本的能力(例如 HTML),以及关联类型 TemplateData 来包含模板需要的数据:

trait Template {
    type TemplateData;

    fn render(&self, data: &Self::TemplateData) -> String;
}

我想要这样的实现:

struct MyTemplateData<'a> {
    title: &'a str,
    author: &'a str,
    last_updated: DateTime<Utc>,
    body: &'a str,
}

struct MyTemplate;

impl Template for MyTemplate {
    type TemplateData = MyTemplateData<'a>;

    fn render(&self, data: &MyTemplateData<'_>) -> String {
        /* snip */
    }
}

MyTemplateData 需要生命周期参数,因为它有一个 &str。该生命周期只需要持续 render 方法的持续时间,因为没有引用离开该方法,因此我为其使用匿名生命周期。但是如上所述,这段代码不起作用。编译器抱怨关联类型规范中的 'a 未声明。如果我声明它 (impl<'a> Template for ...),那仍然不起作用,因为那时我得到 error[E0207]: the lifetime parameter 'a is not constrained by the impl trait, self type, or predicates.

解决此问题的两种方法是将生命周期参数添加到特征或将其添加到 MyTemplate 正在为其实现的结构。

我真正需要的似乎是一种表达方式,“关联类型将 MyTemplateData<'a> 持续一段时间 'a,但只需根据 'a 选择 'a =15=] 需要在调用它的地方。

我考虑的对吗?有办法吗?

你是对的,你要找的东西叫Generic Associated Types,简称GAT

唯一的问题是它们不稳定,每晚都需要。

有了他们,它看起来像:

#![feature(generic_associated_types)]

trait Template {
    type TemplateData<'a>;

    fn render(&self, data: &Self::TemplateData<'_>) -> String;
}

impl Template for MyTemplate {
    type TemplateData<'a> = MyTemplateData<'a>;

    fn render(&self, data: &MyTemplateData<'_>) -> String {
        /* snip */
    }
}

但是,如果您不能每晚使用,则必须选择您描述的选项之一(最好将生命周期添加到特征中,因为它不绑定到实例而是绑定到方法,即到特征的实现)。