【问题标题】:How to accept an async function as an argument?如何接受异步函数作为参数?
【发布时间】:2020-06-28 06:15:12
【问题描述】:

我想复制将闭包/函数作为参数的行为和人体工程学,就像map 所做的那样:iterator.map(|x| ...)

我注意到一些库代码允许传入异步功能,但这种方法不允许我传入参数:

pub fn spawn<F, T>(future: F) -> JoinHandle<T>
where
    F: Future<Output = T> + Send + 'static,
    T: Send + 'static,
spawn(async { foo().await });

我希望做以下事情之一:

iterator.map(async |x| {...});
async fn a(x: _) {}
iterator.map(a)

【问题讨论】:

  • 我认为你需要一个 Stream 来实现这一点,看看 crate futures
  • @MarioSantini docs.rs/async-std/1.5.0/async_std/stream/… 他们接受的函数似乎并不明显,而是最终结果似乎是异步的。
  • 我想说的是:如果您需要对集合进行异步迭代,您可能需要一个流,这是您可以迭代的功能。

标签: asynchronous rust async-await closures future


【解决方案1】:

async |...| expr 闭包语法可用于启用 async_closure 功能的夜间频道。

#![feature(async_closure)]

use futures::future;
use futures::Future;
use tokio;

pub struct Bar;

impl Bar {
    pub fn map<F, T>(&self, f: F)
    where
        F: Fn(i32) -> T,
        T: Future<Output = Result<i32, i32>> + Send + 'static,
    {
        tokio::spawn(f(1));
    }
}

async fn foo(x: i32) -> Result<i32, i32> {
    println!("running foo");
    future::ok::<i32, i32>(x).await
}

#[tokio::main]
async fn main() {
    let bar = Bar;
    let x = 1;

    bar.map(foo);

    bar.map(async move |x| {
        println!("hello from async closure.");
        future::ok::<i32, i32>(x).await
    });
}

查看2394-async_await RFC了解更多详情

【讨论】:

    【解决方案2】:

    async 函数被有效地脱糖为返回impl Future。一旦知道这一点,就可以结合现有的 Rust 技术来接受函数/闭包,从而产生具有两种泛型类型的函数:

    use std::future::Future;
    
    async fn example<F, Fut>(f: F)
    where
        F: FnOnce(i32, i32) -> Fut,
        Fut: Future<Output = bool>,
    {
        f(1, 2).await;
    }
    

    这也可以写成

    use std::future::Future;
    
    async fn example<Fut>(f: impl FnOnce(i32, i32) -> Fut)
    where
        Fut: Future<Output = bool>,
    {
        f(1, 2).await;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-19
      • 2022-12-13
      • 2023-01-30
      • 2014-08-23
      • 1970-01-01
      • 2019-05-13
      相关资源
      最近更新 更多