Есть ли способ продолжить в фьючерсном потоке for_each? - PullRequest
0 голосов
/ 30 сентября 2019

Я делаю цикл for_each над потоком фьючерсов, полученных через mspc::Receiver

rx.for_each(move |trade| {
    if something_true {
        continue;
    }

    // down here I have computation logic which returns a future
});

Я бы хотел сделать что-то похожее на логику выше.

КонечноЯ мог бы просто сделать оператор if / else, но обе ветви должны возвращать один и тот же тип будущего, что мне сложно сделать, так как будущее, которое я генерирую в своей логике вычислений, представляет собой длинную цепочку грязных будущих. Что заставило меня задуматься, есть ли на самом деле простой способ приблизиться к этому, например, продолжить или что-то в этом роде?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Нет, вы не можете. continue - это синтаксис, который принимается только основным языком Rust, и ящики не могут его использовать.

Вместо этого вы могли бы вернуться раньше:

rx.for_each(move |trade| {
    if true {
        return future::ok(());
    }

    future::ok(())
});

обе ветви должнывернуть тот же тип будущего

Использовать Either или объект в штучной упаковке

rx.for_each(move |trade| {
    if true {
        return Either::A(future::ok(()));
    }

    Either::B(future::lazy(|| future::ok(())))
});

См. также:

Я бы, вероятно, переместил условие в поток так, что for_each никогда его не увидит:

rx.filter(|trade| true)
    .for_each(move |trade| future::ok(()));
0 голосов
/ 30 сентября 2019

Давайте решим две проблемы отдельно. Во-первых, самое простое: если ваша цепочка фьючерсов внутри for_each() не является однородной (они редко будут), рассмотрите возможность возврата в штучной упаковке будущего (то есть Box<dyn Future<Item = _, Error = _>>). Возможно, вам придется заново ввести возвращаемое значение замыкания, поскольку компилятор иногда не получает того, что вы пытаетесь сделать.

Теперь для условия «продолжить, если» - это обычно означает, что вы отфильтровываете определенныеэлементы потока, который указывает, что лучшая функция для вызова может включать filter() или промежуточное состояние - то есть возвращать будущее, тип элемента которого Option<_>, и затем фильтровать на основе этого в следующем члене цепочки.

...