最近的一篇文章探讨了从使用 py03 的应用程序的结构中删除生命周期参数的问题。在那个问题中,我们有一个特征
pub trait GetIter {
type IntoIter: IntoIterator<Item=usize>;
fn get_iter( &self ) -> Self::IntoIter;
}
我们想在类型
GetIter
上实现T
,在&T
实现GetIter
的特殊情况下。这种情况会出现在类型IntoIter
需要一些只能由引用提供的生命周期参数的用例中。 prio 帖子对此有一个很好的解决方案,它涉及将 T
包装在一个结构中,该结构将 interator 的内容转储到向量中,从而消除了生命周期要求。
但是有一点复杂。一些应用程序需要几个不同的特征,它们都共享与
GetIter
相同的结构(即,每个特征都返回一个可迭代对象)。假设我们有GetIter
和GetIter2
。每个可迭代对象都有不同的用途,但用例要求它们都运行在同一类型的项目上。为了执行此要求,我们定义了一个辅助特征
pub trait SharedType{ type Item; }
在实践中,我们通常在实现
SharedType
时不需要GetIter
,但在编写使用该实现的下游代码时它会变得很有用。要将 SharedType
与 NoRef<T>
集成,我们想做如下事情
impl < T > SharedType for NoRef< T >
where for <'a>
&'a T: SharedType {
type Item = <&'static T as SharedType>::Item;
}
pub trait GetIter2: SharedType {
type IntoIter: IntoIterator< Item= <Self as SharedType>::Item >;
fn get_iter( &self ) -> Self::IntoIter;
}
impl < T > GetIter2 for NoRef< T >
where for <'a>
&'a T: GetIter2 + SharedType,
{
type IntoIter = Vec< <Self as SharedType>::Item >;
fn get_iter( & self )-> Self::IntoIter {
(&self.inner).get_iter().into_iter().collect()
}
}
但终生并发症再次出现
error[E0310]: the parameter type `T` may not live long enough
--> src/matrices/matrix_types/oracle_deref.rs:31:17
|
31 | type Item = <&'static T as SharedType>::Item;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
28 | impl < T: 'static > SharedType for NoRef< T >
| +++++++++
error[E0310]: the parameter type `T` may not live long enough
--> src/matrices/matrix_types/oracle_deref.rs:43:21
|
43 | type IntoIter = Vec< <Self as SharedType>::Item >;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
39 | impl < T: 'static > GetIter2 for NoRef< T >
| +++++++++
For more information about this error, try `rustc --explain E0310`.
问题的症结似乎是提取关联类型
<&T as IntoIterator>::Item
,而 Rust 没有在引用&T
上要求明确的生命周期参数。 HRTB 技巧在其他情况下效果很好,但我不确定这个。
Aside 您可以玩一些游戏来尝试回避这个问题。例如,您可以在
SharedType
和 T
上实现 &T
,然后在 T
的实现中使用 GetIter2
的关联类型。这通常是可行的,即使在 GetIter2
上实施 T
不是。这条路线可能可行,但我们已经尝试了几种不同的方法,但还没有成功。它也似乎有点不雅,尽管这是一个较小的问题。