我如何返回具有多个生存期的impl迭代器?

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

我在impl特质的一生中遇到麻烦。我正在尝试使以下代码起作用:

struct Foo<'op, Input> {
    op: Box<dyn Fn(Input) -> i32 + 'op>,
}

impl<'op, Input> Foo<'op, Input> {
    fn new<Op>(op: Op) -> Foo<'op, Input>
    where
        Op: Fn(Input) -> i32 + 'op,
    {
        Foo { op: Box::new(op) }
    }

    fn apply<'input_iter, InputIter>(
        self,
        input_iter: InputIter,
    ) -> impl Iterator<Item = i32> + 'op + 'input_iter
    where
        InputIter: IntoIterator<Item = Input> + 'input_iter,
    {
        input_iter.into_iter().map(move |input| (self.op)(input))
    }
}

Playground

这给我以下错误:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/lib.rs:20:36
   |
20 |         input_iter.into_iter().map(move |input| (self.op)(input))
   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime 'op as defined on the impl at 5:6...
  --> src/lib.rs:5:6
   |
5  | impl<'op, Input> Foo<'op, Input> {
   |      ^^^
   = note: ...so that the types are compatible:
           expected Foo<'_, _>
              found Foo<'op, _>
note: but, the lifetime must be valid for the lifetime 'input_iter as defined on the method body at 13:14...
  --> src/lib.rs:13:14
   |
13 |     fn apply<'input_iter, InputIter>(
   |              ^^^^^^^^^^^
note: ...so that return value is valid for the call
  --> src/lib.rs:16:10
   |
16 |     ) -> impl Iterator<Item = i32> + 'op + 'input_iter
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

这是我对所涉及生命的理解。 Foo拥有一个op,这是一个闭包,可能在其中某个地方有一个引用,因此它可能有一定的寿命。这由'op表示,并且Foo受约束以致无法生存。到目前为止,一切都很好。

在apply()中,我们的想法是我们要消耗一个input_iter和self并返回使用self.op映射的input_iter中每个元素的迭代器。 input_iterator也可能包含引用,因此它可能具有自己的生命周期界限,以'input_iter表示。

我想要返回一个拥有self和input_iter所有权的迭代器。这样做时,必须使用它们的生命周期参数,以确保它不超过input_iter引用或op引用。我以为impl Iterator<Item = i32> + 'op + 'input_iter可以做到这一点,但我似乎在某个地方走错了路。

这也很奇怪,它抱怨关闭。我知道闭包不能超过'op,因为它需要运算符及其引用的所有权。这是很合理的。我不明白的是为什么它需要活到'input_iter一样长。闭包和输入迭代器根本不需要关心。连接它们的唯一一件事是它们都具有相同的所有者(输出迭代器)。

我在这里想念什么?

rust lifetime
1个回答
0
投票

Lifetime参数并非总是代表对象(或借用)的exact

© www.soinside.com 2019 - 2024. All rights reserved.