从引用中提取关联类型,而不指定生命周期

问题描述 投票:0回答:0

最近的一篇文章探讨了从使用 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
不是。这条路线可能可行,但我们已经尝试了几种不同的方法,但还没有成功。它也似乎有点不雅,尽管这是一个较小的问题。

rust traits lifetime associated-types pyo3
© www.soinside.com 2019 - 2024. All rights reserved.