rust 一个将异步闭包应用于互斥体内容的组合子?[副本]

xpcnnkqh  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(172)

此问题已在此处有答案

Calling a generic async function with a (mutably) borrowed argument(1个答案)
8天前关闭
在我所提出的方法中,run函数编译失败,因为闭包的返回类型取决于可变引用的生存期。我无法表达F上的正确界限来修复它。这可能吗?

pub async fn with_mutex<'a, I, O, F, Fut>(mutex: &'a Mutex<I>, f: F) -> O
where
  // F: for<'b> (FnOnce(&'b mut I) -> impl (Future<Output = O> + 'b)),
  F: FnOnce(&mut I) -> Fut + 'a,
  Fut: Future<Output = O> + 'a,
{
  let mut guard = mutex.lock().await;
  f(&mut guard).await
}

pub async fn run() {
  let mutex = Mutex::new(5);
  let fut = with_mutex(&mutex, |value| async {
    *value += 1;
  })
  .await;
}
7d7tgy0s

7d7tgy0s1#

遗憾的是,Rust的绑定语法还没有足够的表达能力来支持一个闭包的HRTB,该闭包的返回类型是另一个绑定在其中一个HRTB生命周期上的泛型类型。
最常见的解决方法是要求闭包返回一个盒装的将来。这并不理想,但通常如果你在做异步的事情,那么你等待的东西将比堆分配和dyn Future增加的间接慢几个数量级。

use std::future::Future;
use futures::lock::Mutex;
use futures::future::BoxFuture;

pub async fn with_mutex<I, O, F>(mutex: &Mutex<I>, f: F) -> O
where
  F: for<'a> FnOnce(&'a mut I) -> BoxFuture<'a, O>,
{
  let mut guard = mutex.lock().await;
  f(&mut guard).await
}

pub async fn run() {
  let mutex = Mutex::new(5);
  let fut = with_mutex(&mutex, |value| Box::pin(async {
    *value += 1;
  }))
  .await;
}

相关问题