迭代器有多个生命周期参数时,内涵式迭代器失败。

问题描述 投票:2回答:1

我的代码看起来(有点)像这样。

struct OutputIterator<'r, 'i: 'r> {
    input_handler: &'r mut InputHandler<'i>
}

impl<'r, 'i> Iterator for OutputIterator<'r, 'i> {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        self.input_handler.inputs.next().map(|x| x * 2)
    }
}

struct InputHandler<'a> {
    inputs: Box<dyn Iterator<Item = i32> + 'a>
}

impl<'a> InputHandler<'a> {
    fn outputs<'b>(&'b mut self) -> OutputIterator<'b, 'a> {
        OutputIterator { input_handler: self }
    }
}

fn main() {
    let mut input_handler = InputHandler {
        inputs: Box::new(vec![1,2,3,4,5].into_iter())
    };
    for output in input_handler.outputs() {
        println!("{}", output);
    }
}

基本上,用户可以提供一个输入的迭代器,然后得到一个输出的迭代器(在我真正的代码中,输入和输出之间的连接要复杂得多,涉及一堆内部状态。多个输入可能走向一个输出,反之亦然)。)

这样做是可行的,但我想把它改为使用 impl Iterator 既要掩盖 OutputIterator 类型,并允许在测试中更容易地用一个假的返回类型进行替换。我最好的尝试是这样修改InputHandler impl。

impl<'a> InputHandler<'a> {
    fn outputs<'b>(&'b mut self) -> impl Iterator<Item = i32> + 'b {
        OutputIterator { input_handler: self }
    }
}

不幸的是,这让我。error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds

有什么办法能让它工作?对于接口来说,重要的是 InputHandler 取一个具有一定寿命的迭代器,这显然要传递给 OutputIterator 某种程度上,但我真的很想把这些细节从调用者那里抽象出来。原则上,调用者应该只需要担心是否确保输入的 IteratorInputHandler 超生 OutputIterator 所以,我认为逻辑上的寿命约束在 OutputIterator 这里是这两个中较小的一个?如果能弄清楚为什么会出现这个错误,或者如何解决这个问题,那就太好了!

如果有帮助,这里有一个 锈迹斑斑 与其中的代码。

rust iterator lifetime
1个回答
1
投票

使用以下的变通方法 https:/github.comrust-langrustissues34511#issuecomment-373423999。,通过 https:/stackoverflow.coma505485381757964。:

trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}

impl<'a> InputHandler<'a> {
    fn outputs<'b>(&'b mut self) -> impl Iterator<Item = i32> + Captures<'a> + 'b {
        OutputIterator { input_handler: self }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.