gpt4 book ai didi

rust - 是否可以为异步函数创建类型别名?

转载 作者:行者123 更新时间:2023-12-03 11:26:47 27 4
gpt4 key购买 nike

我想创建一个类型别名来促进函数的闭包,而用户不必考虑函数的参数和返回签名。这将翻译这段代码:

async fn some_func(s: &mut Context<Props>) -> VNode {
// some function body...
}

进入这段代码:

static SomeFunc: FC<Props> = |ctx| async {
// some function body
};

在 JavaScript 中,这将在常​​规函数简写上使用 const 闭包函数定义。

对于常规函数,这工作正常:

type FC<T: Props> = fn(&mut Context<T>) -> Vnode;

然后,静态闭包被提升为函数指针。

但是,impl Future 不能在类型别名中使用(甚至在 1.51 nightly 上也不行),而且我也不能在类型别名中使用通用特征边界。我不知道这是否可行,但很好奇是否有类型别名可用于异步 fns 的方法。

为什么?

我正在设计的 API 将函数作为输入(而不是结构或特征对象),我想让它易于使用。

最佳答案

你不能直接这样做,因为每个 async fn 都有不同的返回类型,即使 future 的计算结果是相同的类型。这是因为每个 async fn 都有自己独特的 Future返回的类型。

为此,您必须使用特征对象 (dyn Fn) 而不是函数指针 (fn()) 作为类型。您要找的类型是

use futures::future::BoxFuture;

type FC<T> = Box<dyn Send + Sync + for<'a> Fn(&'a mut Context<T>) -> BoxFuture<'a, Vnode>>;

上述类型将充当返回 Future 的函数。 ,但是需要一个转换步骤才能将普通的异步 fn 转换为上述类型的函数。

可以按如下方式执行此转换:

Box::new(|context| Box::pin(my_async_fn(context)))

它也可以使用 futures crate 编写。使用 .boxed() 的版本在某些情况下会帮助类型检查器并避免 Box::pin 出现的一些错误版本可以给。

use futures::future::FutureExt;

Box::new(|context| my_async_fn(context).boxed())

由于我们在这种情况下使用的特定类型别名涉及生命周期,因此无法为上述定义方便的转换。也就是说,当参数不是引用时,您可以这样做:

use futures::future::BoxFuture;

type AsyncFnPtr = Box<dyn Send + Sync + Fn(SomeArg) -> BoxFuture<'static, RetValue>>;

fn convert<F, Fut>(func: F) -> AsyncFnPtr
where
F: Send + Sync + 'static,
F: Fn(SomeArg) -> Fut,
Fut: Send + 'static,
Fut: Future<Output = RetValue>,
{
Box::new(|context| Box::pin(func(context)))
}

其他资源:

  1. What does for<'a> mean?
  2. Why does the + 'static not result in a memory leak?
  3. A thread on URLO on the same topic.

关于rust - 是否可以为异步函数创建类型别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65696254/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com