rust 在Struct中存储借用引用的迭代器

ggazkfy8  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(142)

我是Rust的新手,像许多人一样,发现很难掌握窍门。我了解基本情况,但我不太明白如何使这一工作。
我试图实现一个抽象的数据结构,它包含一个记录集合。一个要求是数据结构所引用的记录集合表示为Iterator,因为有时记录将从磁盘读取,有时它们将来自内存,有时则来自缓存之类的地方。数据结构本身并不关心记录是如何返回的。它只需要能够迭代它们并过滤/Map它们等。
我的实际代码比这更复杂,但我已经尽可能地提炼了这一点,以说明我遇到的问题。
假设我有一个类型Record。那是什么并不重要。如果我有一个名为recordsVec<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(),并构造一个新的迭代器,它基本上做同样的事情,但如果有必要,它会满足编译器的期望。

qco9c6ql

qco9c6ql1#

排名较高的生存期不能只出现在关联类型中而不出现在泛型中。我不认为这是不可能实现的,据我所知,它曾经被允许过一次,但被错误地实现了,导致不合理,因为特质求解器有时会为同一示例选择不同的生命周期。所以这只是被禁止的。我不知道这是否很难实现,或者只是没有人打扰。
但这并不重要,因为你的定义是不正确的。以std::slice::Iter<'a, Record>为例,它是在执行vec.iter()时创建的。此结构体不为 any 生存期'b实现Iterator<Item = &'b Record>,仅为生存期'a-向量的生存期。所以你需要的是一个泛型参数,而不是一个更高排名的trait绑定:

pub trait RecordIterator<'a>: Iterator<Item = &'a Record> {}

impl<'a, T> RecordIterator<'a> for T where T: Iterator<Item = &'a Record> {}

pub struct RecordSet<'a> {
    records_iter: Box<dyn RecordIterator<'a> + 'a>,
}

相关问题