我的特征代表了模板中呈现文本(例如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
需要生命周期参数,因为它具有&amp; str
。由于没有参考文献离开该方法,因此该生命周期只需要持续 Render
方法的持续时间,因此我使用匿名的寿命。但是如上所述,此代码不起作用。编译器抱怨'a
在关联类型规范中未申报。如果我声明它( stramp&lt;'a&gt; toRefe for ...
),那仍然不起作用,因为那时我会得到错误[e0207]:lifetime参数受到IMP的特征,自我类型或谓词的约束。
解决此问题的两种方法是将生命周期参数添加到特征或将其添加到 myTemplate
struct struct struct struct struct struct struct已实现它。 。
- 将寿命添加到
myTemplate
没有多大意义,因为它不包含任何参考成员(或实际上,在此简单示例中根本没有任何成员)。
- 将其添加到特征似乎没有意义,因为生命确实仅适用于
渲染
方法,而不是整个特征(例如,我可以想象有第二种方法,例如 get_rendered_size
将具有自己的寿命参数)。
- 这两种方式都有非常不便的缺点,即在使用特质/结构的任何地方都必须添加生命周期注释。
似乎我真正需要的是一种说:“关联的类型将是 myTemplatedAta&lt;'a&gt;
在某些寿命'a 中,但只需选择 '
基于渲染
我在考虑这一点吗?
I have this trait representing the ability to render text (e.g. HTML) from a template, and an associated type TemplateData
to contain the data the template needs:
trait Template {
type TemplateData;
fn render(&self, data: &Self::TemplateData) -> String;
}
I want to have an implementation like this:
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
needs a lifetime parameter because it has a &str
. That lifetime only needs to last the duration of the render
method since no references leave the method, so I use an anonymous lifetime for it. But as written above, this code doesn't work. The compiler complains that 'a
in the associated type specification is undeclared. If I declare it (impl<'a> Template for ...
), that still doesn't work, because then I get error[E0207]: the lifetime parameter 'a is not constrained by the impl trait, self type, or predicates.
The two ways to fix this are to add a lifetime parameter to the trait or to add it to the MyTemplate
struct it's being implemented for.
- Adding a lifetime to
MyTemplate
doesn't make much sense because it doesn't contain any reference members (or in fact, any members at all in this simple example).
- Adding it to the trait doesn't seem to make sense because the lifetime really only applies to the
render
method, not trait-wide (for example, I could imagine having a second method like get_rendered_size
that would have its own lifetime parameter).
- Both ways have the very inconvenient drawback that lifetime annotations then have to be added wherever the trait/struct is used.
What it seems like I really need is a way to say, "the associated type will be MyTemplateData<'a>
for some lifetime 'a
, but just pick 'a
based on whatever render
needs where it's called.
Am I thinking about this right? Is there a way to do that?
发布评论
评论(1)
您是正确的,您要寻找的是,或简称GAT。
唯一的问题是它们不稳定,需要每晚。
与他们在一起,看起来好像:
但是,如果您不能每晚使用,则必须选择您描述的选项之一(最好将生命周期添加到特征中,因为它不是与实例相关的,而是与该方法相关的,即实施特征)。
You are correct, and what you are looking for is called Generic Associated Types, or GAT for short.
The only problem is they're unstable and require nightly.
With them, it looks like:
However, if you cannot use nightly, you have to choose one of the options you described (it is probably better to add the lifetime to the trait, since it is not tied to an instance but to the method, i.e. to an implementation of the trait).