如何通过特征及其关联的生存期来加入嵌套BoxFutures?

时间:2019-06-18 14:08:29

标签: async-await rust future traits

我具有AdoptablePet特质,可让您通过fn do_adoption(id: &Self::Id) -> BoxFuture<'static, Result<Self, Self::Error>>;异步收养宠物。

我有一个Dog特质,可以接受(pub trait Dog: AdoptablePet),在允许您实际收养宠物之前,需要关联的AdoptingPersonadoption_policyadoption_policy只是一个函数,它返回返回Result的盒装期货数组。

当我去创建同时实现PitbullDog的{​​{1}}时,一切正常,但是一旦我尝试默认实现{{1} }(对于所有AdoptablePet都是一样的),我无法在所有盒装期货的加入之间获得正确的引用。

当我尝试adoption_policy Pitbull join_all时,它包含对盒装期货的引用,而不是对盒装期货本身的引用。尝试映射和取消引用它们时,出现借用检查器错误(请参见代码中的adoption_policy

Vec

我有点迷茫。如果我没有在[EXAMPLE B]中使用error[E0277]: the trait bound `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>: core::future::future::Future` is not satisfied --> src/lib.rs:70:13 | 70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| { | ^^^^^^^^ the trait `core::future::future::Future` is not implemented for `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>` | = help: the following implementations were found: <std::pin::Pin<P> as core::future::future::Future> = note: required by `futures_util::future::join_all::join_all` error[E0599]: no method named `then` found for type `futures_util::future::join_all::JoinAll<&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>>` in the current scope --> src/lib.rs:70:65 | 70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| { | ^^^^ error[E0277]: the trait bound `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>: core::future::future::Future` is not satisfied --> src/lib.rs:70:13 | 70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `core::future::future::Future` is not implemented for `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>` | = help: the following implementations were found: <std::pin::Pin<P> as core::future::future::Future> = note: required by `futures_util::future::join_all::JoinAll` (仅返回join_all,一切正常(请参见代码中的adopt)。这是怎么回事?

代码(也为available in a git repo):

Self::do_adoption(id)

我正在使用期货预览版0.3.0-alpha.16。

1 个答案:

答案 0 :(得分:1)

这是工作版本:

fn adopt(
    adopter: &Self::AdoptingPerson,
    id: &'static Self::Id,
) -> BoxFuture<'static, Result<Self, AdoptionError>> {
    Box::pin(
        join_all(Self::adoption_policy(adopter, id)).then(move |policy_results| {
            let has_policy_failure = policy_results.iter().any(|x| x.is_err());
            if !has_policy_failure {
                Self::do_adoption(id)
            } else {
                Box::pin(future::ready(Err(AdoptionError {})))
            }
        }),
    )
}

更改:

  1. join_all需要拥有期货的所有权,而不是对它们的引用:join_all(Self::adoption_policy(adopter, id))
  2. 必须导入
  3. futures::future::FutureExt才能访问FutureExt::then
  4. anyIterator而非Vec上的方法:policy_results.iter().any(/* ... */)
  5. id必须为'static,这取决于您的限制:id: &'static Self::Id
  6. id需要移到关闭处以防止借用:move |policy_results| { /* ... */ }

另请参阅:

相关问题