如何指定具有生命周期参数的关联类型?
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
正在为其实现的结构。
- 向
MyTemplate
添加生命周期没有多大意义,因为它不包含任何引用成员(或者事实上,在这个简单的示例中根本不包含任何成员)。
- 将它添加到特征中似乎没有意义,因为生命周期实际上只适用于
render
方法,而不适用于特征范围(例如,我可以想象有第二种方法 get_rendered_size
会有自己的生命周期参数)。
- 这两种方式都有一个非常不方便的缺点,即必须在使用 trait/struct 的任何地方添加生命周期注释。
我真正需要的似乎是一种表达方式,“关联类型将 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 */
}
}
但是,如果您不能每晚使用,则必须选择您描述的选项之一(最好将生命周期添加到特征中,因为它不绑定到实例而是绑定到方法,即到特征的实现)。
我有这个特征代表从模板呈现文本的能力(例如 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
正在为其实现的结构。
- 向
MyTemplate
添加生命周期没有多大意义,因为它不包含任何引用成员(或者事实上,在这个简单的示例中根本不包含任何成员)。 - 将它添加到特征中似乎没有意义,因为生命周期实际上只适用于
render
方法,而不适用于特征范围(例如,我可以想象有第二种方法get_rendered_size
会有自己的生命周期参数)。 - 这两种方式都有一个非常不方便的缺点,即必须在使用 trait/struct 的任何地方添加生命周期注释。
我真正需要的似乎是一种表达方式,“关联类型将 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 */
}
}
但是,如果您不能每晚使用,则必须选择您描述的选项之一(最好将生命周期添加到特征中,因为它不绑定到实例而是绑定到方法,即到特征的实现)。