当 &self 的生命周期与结构体不同时

Raf*_*elo 4 lifetime rust

在这个例子中

use std::marker::PhantomData;

pub struct A<'a, T> {
    elements: Vec<B<'a, T>>
}

pub struct B<'a, T> {
    _phantom: PhantomData<&'a T>
}

impl<'a, T> A<'a, T> {
    pub fn iter(& self) -> Iter<'a, T> {
        Iter {
            iter: self.elements.iter(),
        }
    }
}

pub struct Iter<'a, T> {
    iter: std::slice::Iter<'a, B<'a, T>>,
}
Run Code Online (Sandbox Code Playgroud)

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e246ef19b9ae5f1d405bde7c59d456d7

我明白了

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/lib.rs:14:24
   |
14 |             iter: self.elements.iter(),
   |                                 ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
  --> src/lib.rs:12:17
//...
Run Code Online (Sandbox Code Playgroud)

我知道为什么会发生这种情况:elementsinself.elements生命周期只要&self,所以它不可能创建一个Iterwith 生命周期a。简单的解决方案是

pub fn iter(&'a self) -> Iter<'a, T> {
    Iter {
        iter: self.elements.iter(),
    }
}
Run Code Online (Sandbox Code Playgroud)

但后来我被迫借用&self它的整个存在,这导致我遇到其他问题。这里最简单的解决方案是什么?

kmd*_*eko 8

您的Iter实施受到过度限制;你有两个不相关的生命周期,但它们必须是相同的。你应该将它们分开:

impl<'a, T> A<'a, T> {
    pub fn iter(&self) -> Iter<'a, '_, T> {
        Iter {
            iter: self.elements.iter(),
        }
    }
}

pub struct Iter<'a, 'b, T> {
    iter: std::slice::Iter<'b, B<'a, T>>,
}
Run Code Online (Sandbox Code Playgroud)

这样,即使 是'a不变的,您也不会遇到将该生命周期链接到 的问题self。看看它在操场上的工作(还有额外的测试)。