让我们用它作为我们的最小的、可重复的示例 https://stackoverflow.com/help/minimal-reproducible-example:
async fn foo(x: u8) -> u8 {
2 * x
}
struct S {
foo: (),
}
async fn example() {
let s = S { foo };
}
它产生错误:
error[E0308]: mismatched types
--> src/main.rs:10:17
|
10 | let s = S { foo };
| ^^^ expected (), found fn item
|
= note: expected type `()`
found type `fn(u8) -> impl std::future::Future {foo}`
的类型foo
是一个函数指针,它接受一个u8
并返回一些实现该特征的类型std::future::Future
. async fn
实际上只是转换的语法糖-> Foo
into -> impl Future<Output = Foo>
.
我们使我们的结构通用,并在匹配的通用上放置一个特征绑定。在实际代码中,您可能希望对Output
关联类型,但本示例不需要它。然后我们可以像任何其他可调用成员字段一样调用该函数:
async fn foo(x: u8) -> u8 {
2 * x
}
struct S<F>
where
F: std::future::Future,
{
foo: fn(u8) -> F,
}
impl<F> S<F>
where
F: std::future::Future,
{
async fn do_thing(self) {
(self.foo)(42).await;
}
}
async fn example() {
let s = S { foo };
s.do_thing().await;
}
为了更加灵活,您可以使用另一个泛型来存储闭包,而不是仅强制使用函数指针:
struct S<C, F>
where
C: Fn(u8) -> F,
F: std::future::Future,
{
foo: C,
}
impl<C, F> S<C, F>
where
C: Fn(u8) -> F,
F: std::future::Future,
{
async fn do_thing(self) {
(self.foo)(42).await;
}
}
也可以看看:
- 如何通过成员变量调用函数? https://stackoverflow.com/q/27994509/155423
- 如何在 Rust 的结构中存储闭包? https://stackoverflow.com/q/27831944/155423