实现迭代器的代理方法,生命周期冲突

时间:2018-11-22 20:54:37

标签: rust

我正在尝试实现一个迭代器,该迭代器仅将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

Playground

我该如何解决?

2 个答案:

答案 0 :(得分:1)

一种解决方案是指定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()
    }
}

答案 1 :(得分:1)

那么您需要给借阅检查器一种推断寿命的方法。基本上缺少的是以下行之一

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更长。