Ошибка при реализации итератора в структуре с изменяемым временем жизни

Я пытался реализовать итератор над сложной структурой, и для этого я решил использовать вспомогательную структуру, которая указывает на исходную. (для этого мне пришлось использовать время жизни). я написал код для ссылочного итератора, и он работает. но если я пишу тот же код для изменяемой ссылки, он не работает, странно то, что ошибка, похоже, связана со временем жизни, а не с владением

Вот код для перебора ссылки, и он работает:

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`

Может кто-нибудь сказать мне, почему это не работает и почему это работает в первом примере? (даже если время жизни точно такое же)

Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
1
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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 20.11.2022 16:29

@Luca Сообщение об ошибке точно правильное. Ваша первоначальная реализация возвращала ссылки, которые не прожили достаточно долго.

isaactfa 20.11.2022 17:05

Другие вопросы по теме