Прокси-метод для реализации Iterator, конфликт жизни - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь реализовать итератор, который просто передает метод next другому методу в самой структуре.

struct Element<'a>(&'a str);

struct IterStruct<'a> {
    name: &'a str,
}

impl<'a> IterStruct<'a> {
    fn name(&mut self) -> Option<Element> {
        Some(Element(self.name))
    }
}

impl<'a> Iterator for IterStruct<'a> {
    type Item = Element<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.name()
    }
}

Я получаю противоречивые требования для ошибки времени жизни:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/lib.rs:16:14
   |
16 |         self.name()
   |              ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 15:5...
  --> src/lib.rs:15:5
   |
15 | /     fn next(&mut self) -> Option<Self::Item> {
16 | |         self.name()
17 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:16:9
   |
16 |         self.name()
   |         ^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 13:6...
  --> src/lib.rs:13:6
   |
13 | impl<'a> Iterator for IterStruct<'a> {
   |      ^^
   = note: ...so that the types are compatible:
           expected std::iter::Iterator
              found std::iter::Iterator

Детская площадка

Как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

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

impl<'a> IterStruct<'a> {
    fn name(&mut self) -> Option<Element> {
//  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Some(Element(self.name))
    }
}

в fn name(&mut self) -> Option<Element<'a>>.Средство проверки заимствования Rust позаботится обо всем остальном [Playground link] .

Компилятор кажется достаточно умным, чтобы вывести 'a, если он переживет 'self.

0 голосов
/ 23 ноября 2018

Одно из решений - указать, что name переживает IterStruct, в котором оно содержится:

struct Element<'a>(&'a str);

struct IterStruct<'a> {
    name: &'a str,
}

impl<'a> IterStruct<'a> {
    fn name<'s>(&'s mut self) -> Option<Element<'a>>
    where
        'a: 's, // <- specify that name outlives self
    {
        Some(Element(self.name))
    }
}

impl<'a> Iterator for IterStruct<'a> {
    type Item = Element<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.name()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...