rust - 对于具有多个生命周期参数的迭代器,impl Iterator 失败

标签 rust iterator lifetime

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

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 采用具有一定生命周期的迭代器对于接口(interface)很重要,显然必须以某种方式将其传递给 OutputIterator,但我真的很想抽象那些远离来电者的细节。原则上,调用者只需要担心确保输入 IteratorInputHandlerOutputIterator 长,所以我认为逻辑生命周期界限OutputIterator 是这两个中较小的一个吗?清楚地说明为什么会发生此错误或如何修复它会很棒!

如果有帮助,这里是 rust playground里面有代码。

最佳答案

使用 https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 中的解决方法, 通过 https://stackoverflow.com/a/50548538/1757964 :

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 }
    }
}

关于rust - 对于具有多个生命周期参数的迭代器,impl Iterator 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61446984/

相关文章:

rust - 我应该使用什么特征来从文件、TCP 连接、简单字符串中读取字节流......?

python - 如果未使用特定迭代器,类似 zip 的函数将失败

C++ 14制作自定义迭代器,它将经过2并返回修改后的数据

java - 在范围、生命周期方面有什么区别吗?

rust - 使用带有 iter().map() 的函数 - 作为命名函数 vs 作为闭包

rust - rust future `try_filter_map`导致 panic : 'async fn resumed after completion'

rust - 从认证页面返回后是否可以保留全局变量 `window.__TAURI__`?

c++ - 为什么unordered_map没有rbegin()和rend(),而只有begin()和end()

rust - 向非引用类型添加生命周期约束

stream - 如何读取 rocket::Data 到整流罩内的字符串?