假设我们有以下代码:
fn inc(src: u32) -> u32 {
src + 1
}
fn inc2(src: u32) -> u32 {
src + 2
}
type Incrementer = fn(u32) -> u32;
fn increment_printer(inc: Incrementer) {
println!("{}", inc(1));
}
fn main() {
increment_printer(inc);
increment_printer(inc2);
}
两个具有相同签名的函数和一个接受它们指针的第三个函数。运行此代码将导致打印 2\n3。
但类似的某些内容将无法编译:
use core::future::Future;
async fn inc(src: u32) -> u32 {
src + 1
}
async fn inc2(src: u32) -> u32 {
src + 2
}
type Incrementer = fn(u32) -> dyn Future<Output = u32>;
async fn increment_printer(inc: Incrementer) {
println!("{}", inc(1).await);
}
fn main() {
async {
increment_printer(inc).await;
increment_printer(inc2).await;
}
}
18 | increment_printer(inc).await;
| ^^^ expected trait object `dyn Future`, found opaque type
|
= note: expected fn pointer `fn(_) -> (dyn Future<Output = u32> + 'static)`
found fn item `fn(_) -> impl Future {inc}`
我知道每个异步函数都有自己的类型,正如错误中所提到的。是否有可能强制编译器忘记具体类型并将它们视为相似类型?
也许可以强制异步函数返回一个 Box<Future<Output=u32>>
吗?
我不想为了方便而放弃异步函数。同时,我也不想在将异步函数指针传递给函数之前调用 Box::pin()。
如果有更多的选项,那就很有趣了。
force_boxed()
的签名(它可以接受一个函数,而不是FnOnce
本身),并提供了一种不需要将闭包框起来的替代方案,但代价是需要像increment_printer
这样的函数是泛型的。 - user4815162342