Asynchronous 如何使用异步闭包捕获和接受引用

Asynchronous 如何使用异步闭包捕获和接受引用,asynchronous,rust,closures,lifetime,Asynchronous,Rust,Closures,Lifetime,我试图将一个返回Future的闭包传递给一个异步函数,并将此闭包作为异步谓词调用(类似于异步.filter或其他高阶函数) 此谓词将其输入作为引用接收。我找到了如何为不捕获其环境的纯谓词实现它: 输入BoxFuture>; //////////////////////////////////////////////////////////////////////////////// //1->Closure只使用内部参数// ///////////////////////////////////

我试图将一个返回
Future
的闭包传递给一个异步函数,并将此闭包作为异步谓词调用(类似于异步
.filter
或其他高阶函数)

此谓词将其输入作为引用接收。我找到了如何为不捕获其环境的纯谓词实现它:

输入BoxFuture>;
////////////////////////////////////////////////////////////////////////////////
//1->Closure只使用内部参数//
////////////////////////////////////////////////////////////////////////////////
///运行计算并检查其输出是否为空
fn run1 impl Future+'a{
异步移动{
让is_ok=compute_and_check1(|b:&[u8]| Box::pin(异步移动{
b、 len()>0//仅使用内部参数
}));
让我们等待;
dbg!(是ok1);
}
}
///计算一些字节(可能很复杂/使用异步),然后检查它们的有效性
///使用用户提供的函数,最后进行一些清理并返回。
异步fn计算和检查1(检查:F)->bool
哪里
F:对于BoxFuture=Pin(预期值:&'a[u8])->impl Future+'a{
异步移动{
让is_ok=compute_and_check2(|b:&[u8]| Box::pin(异步移动{
应为.len()>0//仅使用环境
}));
让我们等待;
dbg!(是ok2);
}
}
///计算一些字节(可能很复杂/使用异步),然后检查它们的有效性
///使用用户提供的函数,最后进行一些清理并返回。
异步fn计算和校验2 FNOCE(&'r[u8])->BoxFuture=Pin(预期值:&'a[u8])->impl Future+'a{
异步移动{
让is_ok=compute_and_check3(|b:&[u8]| Box::pin(异步移动{
b==预期//同时使用输入和环境
}));
让我们等待;
dbg!(是ok2);
}
}
///计算一些字节(可能很复杂/使用异步),然后检查它们的有效性
///使用用户提供的函数,最后进行一些清理并返回。
异步fn计算和检查3 FNOCE(&'r[u8])->BoxFuture
{
让字节=[0u8;128];
让is_ok=检查(&bytes)。等待;
删除(字节);
你还好吗
}

此代码未编译,因为我要求闭包返回
BoxFuture
,但这不是合法语法:

error[E0226]: only a single explicit lifetime bound is permitted
  --> src/main.rs:89:51
   |
89 |     F: for<'r> FnOnce(&'r [u8]) -> BoxFuture<'r + 'a, bool>
   |                                                   ^^
  • 错误:生命周期可能不够长
    -->src/main.rs:17:47
    |
    17 | let is_ok=compute_and_check2(| b:&[u8]| Box::pin(异步移动{
    |  ________________________________________-____-_^
    | |                                        |    |
    
    || |闭包的返回类型为PinI我不确定您是否可以在不使用“作用域”的情况下完成此操作运行时。有,但我从未使用过它,而且它看起来没有太多使用,所以我不会太乐观。不过,您可以使用引用计数来做同样的事情:感谢您的回复。我问题的根本原因是我实际上想要类似于
    tokio scoped
    的东西,但这个库没有维护。结构化并发一般来说,这对Tokio来说是一个难题。关于使用
    Arc
    ,它的工作原理是使环境保持静态:在这种情况下,它很好,但它仍然是一种解决方法,需要在不需要的地方引入参考计数。
    error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
      --> src/main.rs:17:67
       |
    17 |       let is_ok = compute_and_check1(|b: &[u8]| Box::pin(async move {
       |  ___________________________________________________________________^
    18 | |       b == expected
    19 | |     }));
       | |_____^
       |
    note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 15:9...
      --> src/main.rs:15:9
       |
    15 | fn run3<'a>(expected: &'a [u8]) -> impl Future<Output=()> + 'a {
       |         ^^
    note: ...so that the types are compatible
      --> src/main.rs:17:67
       |
    17 |       let is_ok = compute_and_check1(|b: &[u8]| Box::pin(async move {
       |  ___________________________________________________________________^
    18 | |       b == expected
    19 | |     }));
       | |_____^
       = note: expected `(&[u8], &[u8])`
                  found `(&[u8], &'a [u8])`
    note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the body at 17:36...
      --> src/main.rs:17:36
       |
    17 |       let is_ok = compute_and_check1(|b: &[u8]| Box::pin(async move {
       |  ____________________________________^
    18 | |       b == expected
    19 | |     }));
       | |______^
    note: ...so that the expression is assignable
      --> src/main.rs:17:47
       |
    17 |       let is_ok = compute_and_check1(|b: &[u8]| Box::pin(async move {
       |  _______________________________________________^
    18 | |       b == expected
    19 | |     }));
       | |______^
       = note: expected `Pin<Box<dyn Future<Output = bool> + Send>>`
                  found `Pin<Box<dyn Future<Output = bool> + Send>>`
    
    error: lifetime may not live long enough
      --> src/main.rs:17:47
       |
    17 |       let is_ok = compute_and_check2(|b: &[u8]| Box::pin(async move {
       |  ________________________________________-____-_^
       | |                                        |    |
       | |                                        |    return type of closure is Pin<Box<(dyn Future<Output = bool> + Send + '2)>>
       | |                                        let's call the lifetime of this reference `'1`
    18 | |       b == expected
    19 | |     }));
       | |______^ returning this value requires that `'1` must outlive `'2`