У меня проблемы с продолжительностью жизни по признаку. Я пытаюсь заставить работать следующий код:
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))
}
}
( Детская площадка )
Это дает мне следующую ошибку:
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, и Foo ограничен так, что он не может пережить это. Пока все хорошо.
В apply () идея состоит в том, что мы хотим использовать input_iter и self и возвращать итератор каждого элемента в input_iter, сопоставленного с помощью self.op. Аргумент input_iterator также может содержать ссылки, поэтому он может иметь свои собственные границы времени жизни, обозначаемые как «input_iter».
Я хочу вернуть итератор, который принимает владение как self, так и input_iter. При этом он должен будет принять оба их параметра времени жизни, чтобы гарантировать, что он не переживет ни ссылки input_iter, ни ссылки op. Я думал, что impl Iterator<Item = i32> + 'op + 'input_iter
достигнет этого, но я, кажется, где-то сделал неправильный поворот.
Также странно, что он жалуется на закрытие. Я понимаю, что закрытие не может пережить 'операции, потому что это берет на себя ответственность оператора и его ссылок. Это имеет смысл. Чего я не понимаю, так это того, почему он должен жить так долго, как 'input_iter. Закрытие и входной итератор вообще не должны заботиться друг о друге;единственное, что их связывает, это то, что они оба имеют одного и того же владельца (выходной итератор).
Чего мне здесь не хватает?