我是Rust的新手,像许多人一样,发现很难掌握窍门。我了解基本情况,但我不太明白如何使这一工作。
我试图实现一个抽象的数据结构,它包含一个记录集合。一个要求是数据结构所引用的记录集合表示为Iterator
,因为有时记录将从磁盘读取,有时它们将来自内存,有时则来自缓存之类的地方。数据结构本身并不关心记录是如何返回的。它只需要能够迭代它们并过滤/Map它们等。
我的实际代码比这更复杂,但我已经尽可能地提炼了这一点,以说明我遇到的问题。
假设我有一个类型Record
。那是什么并不重要。如果我有一个名为records
的Vec<Record>
,那么我可以使用records.iter()
获得&Record
示例的迭代器,对吗?这正是我需要存储在结构体字段中的内容,只是它需要是抽象的,而不是专门绑定到Vec<T>
的实现。
我试着这样定义一个特征:
trait RecordIterator: Iterator<Item = &Record> {}
以及保存此类型trait对象的结构体:
struct RecordSet {
records_iter: Box<dyn RecordIterator>,
}
当然,这不会编译,因为我需要指定生存期。编译器建议使用更高秩的生存期,因此:
trait RecordIterator: for<'a> Iterator<Item = &'a Record> {}
impl<T> RecordIterator for T where T: for<'a> Iterator<Item = &'a Record> {}
但这给了我一个错误:
Compiling playground v0.0.1 (/playground)
error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
--> src/main.rs:3:40
|
3 | trait RecordIterator: for<'a> Iterator<Item = &'a Record> {}
| ^^^^^^^^^^^^^^^^^
error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
--> src/main.rs:5:56
|
5 | impl<T> RecordIterator for T where T: for<'a> Iterator<Item = &'a Record> {}
| ^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0582`.
error: could not compile `playground` due to 2 previous errors
下面是一个link到操场包含此代码。
我需要做什么来将这种迭代器存储在结构中(只要它是有效的)?我也很高兴完全避免使用Vec<T>::iter()
,并构造一个新的迭代器,它基本上做同样的事情,但如果有必要,它会满足编译器的期望。
1条答案
按热度按时间qco9c6ql1#
排名较高的生存期不能只出现在关联类型中而不出现在泛型中。我不认为这是不可能实现的,据我所知,它曾经被允许过一次,但被错误地实现了,导致不合理,因为特质求解器有时会为同一示例选择不同的生命周期。所以这只是被禁止的。我不知道这是否很难实现,或者只是没有人打扰。
但这并不重要,因为你的定义是不正确的。以
std::slice::Iter<'a, Record>
为例,它是在执行vec.iter()
时创建的。此结构体不为 any 生存期'b
实现Iterator<Item = &'b Record>
,仅为生存期'a
-向量的生存期。所以你需要的是一个泛型参数,而不是一个更高排名的trait绑定: