Я пытался реализовать итератор над сложной структурой, и для этого я решил использовать вспомогательную структуру, которая указывает на исходную. (для этого мне пришлось использовать время жизни). я написал код для ссылочного итератора, и он работает. но если я пишу тот же код для изменяемой ссылки, он не работает, странно то, что ошибка, похоже, связана со временем жизни, а не с владением
Вот код для перебора ссылки, и он работает:
struct Iter<'a>{
vec: &'a i32// i32 is just an example, assume is a more complex strict
}
impl<'a> Iterator for Iter<'a>{
type Item = &'a i32;
fn next(&mut self) -> Option<Self::Item> {
Option::Some(self.vec)//assume this actually iterate over something, again... is just an example
}
}
Вот тот же код, но с изменяемой ссылкой и он не компилируется:
struct IterMut<'a>{
vec: &'a mut i32
}
impl<'a> Iterator for IterMut<'a>{
type Item = &'a mut i32;
fn next(&mut self) -> Option<Self::Item> {
Option::Some(self.vec)
}
}
Ошибка, которую я получаю, следующая:
error: lifetime may not live long enough
--> src\main.rs:19:9
|
16 | impl<'a> Iterator for IterMut<'a>{
| -- lifetime `'a` defined here
17 | type Item = &'a mut i32;
18 | fn next(&mut self) -> Option<Self::Item> {
| - let's call the lifetime of this reference `'1`
19 | Option::Some(self.vec)
| ^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
Может кто-нибудь сказать мне, почему это не работает и почему это работает в первом примере? (даже если время жизни точно такое же)
Проблема в том, что общие ссылки являются Copy, а изменяемые — нет. Для вашего простого примера это сработает.
struct IterMut<'a>{
vec: Option<&'a mut i32>
}
impl<'a> Iterator for IterMut<'a>{
type Item = &'a mut i32;
fn next(&mut self) -> Option<Self::Item> {
self.vec.take()
}
}
Суть в том, что вы не можете удержать ссылку, которую возвращаете.
@Luca Сообщение об ошибке точно правильное. Ваша первоначальная реализация возвращала ссылки, которые не прожили достаточно долго.
Так вы говорите, что это действительно была проблема владения, и, возможно, сообщение об ошибке было немного далеким?