У меня есть структура, которая лениво загружает данные во внутренний вектор (но для примера это опущено). Затем я реализую IntoIterator
и Iterator
для типа IntoIterator:
struct EntryOwned(u32);
struct Entry<'a>(&'a u32);
impl<'a> EntryOwned {
fn to_entry(&'a self) -> Entry<'a> {
Entry(&self.0)
}
}
struct LazyStruct {
cache: Vec<EntryOwned>,
}
impl<'a> LazyStruct {
fn new(data: Vec<EntryOwned>) -> LazyStruct {
Self {
cache: data,
}
}
fn get_entry(&'a self, index: usize) -> Option<Entry<'a>> {
match self.cache.get(index) {
Some(entry_owned) => Some(entry_owned.to_entry()),
None => None,
}
}
}
impl<'a> IntoIterator for &'a mut LazyStruct {
type Item = Entry<'a>;
type IntoIter = LazyStructIter<'a>;
fn into_iter(self) -> Self::IntoIter {
LazyStructIter {
inner: self,
current_index: 0,
}
}
}
struct LazyStructIter<'a> {
inner: &'a mut LazyStruct,
current_index: usize,
}
impl<'a> LazyStructIter<'a> {
fn next_item(&'a mut self) -> Option<Entry<'a>> {
if self.current_index > self.inner.cache.len() {
return None;
}
let ret = self.inner.get_entry(self.current_index);
self.current_index += 1;
ret
}
}
impl<'a> Iterator for LazyStructIter<'a> {
type Item = Entry<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.next_item()
}
}
, что приводит к проблеме на всю жизнь:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:64:14
|
64 | self.next_item()
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 63:5...
--> src/main.rs:63:5
|
63 | / fn next(&mut self) -> Option<Self::Item> {
64 | | self.next_item()
65 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:64:9
|
64 | self.next_item()
| ^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 60:6...
--> src/main.rs:60:6
|
60 | impl<'a> Iterator for LazyStructIter<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:64:14
|
64 | self.next_item()
| ^^^^^^^^^
= note: expected `&mut LazyStructIter<'_>`
found `&mut LazyStructIter<'a>`
Время жизни ссылок должно быть привязано на LazyStruct
, но я не могу изменить черту Iter, не принимаю никаких указателей времени жизни. Я уже проверил некоторые ответы на подобные проблемы: Итератор, возвращающий элементы по ссылке, вопрос времени жизни Как мне написать итератор, который возвращает ссылки на себя?
EDIT : Entry
является более сложной структурой данных, и ее невозможно скопировать. Я должен связать его с определенным временем жизни c, так как оно содержит ссылки на вещи.
Один из них указывает, что итератор должен хранить ссылку на исходную коллекцию вместо того, чтобы владеть ею, поскольку ему не разрешено вернуть ссылку с собственной жизнью. Но я не мог заставить это работать. Итак, как мне играть здесь ссылки?
Вот пример игровая площадка
Любая помощь приветствуется, спасибо всем заранее!