某些库(例如 Bevy 或 Actix Web)具有接受带有任意数量参数的用户定义函数的函数。
Actix 网站:
async fn fn1(path: web::Path<String>) -> impl Responder {
// not important
}
async fn fn2(_req: HttpRequest) -> impl Responder {
// not important
}
let app = App::new()
.route("/", web::get().to(fn2))
.route("/{name}", web::get().to(fn1));
Run Code Online (Sandbox Code Playgroud)
贝维:
fn fn1(mut commands: Commands) {}
fn fn2(mut commands: Commands, time: Res<Time>) {}
App::new().add_system(fn1).add_system(fn2);
Run Code Online (Sandbox Code Playgroud)
正如您在这两种情况下所看到的,函数web::get().to(), add_system()接受具有动态数量和类型的参数的函数作为其参数。它们不是宏。我怎样才能实现这个目标?这个有名字吗?谢谢
由于函数可以实现特征,因此解决方案是定义一个表示“可以充当回调函数”的特征,然后为每个函数手动实现它,直到大量参数。在 中actix,这是通过.to(f)采取一些实现该Handler特征的方法来完成的:
pub fn to<F, Args>(mut self, handler: F) -> Self
where
F: Handler<Args>,
Args: FromRequest + 'static,
F::Output: Responder + 'static,
Run Code Online (Sandbox Code Playgroud)
其中Handler定义为:
pub trait Handler<Args>: Clone + 'static {
type Output;
type Future: Future<Output = Self::Output>;
fn call(&self, args: Args) -> Self::Future;
}
Run Code Online (Sandbox Code Playgroud)
函数参数的实现创建如下:
/// Generates a [`Handler`] trait impl for N-ary functions where N is specified with a sequence of
/// space separated type parameters.
///
/// # Examples
/// ```ignore
/// factory_tuple! {} // implements Handler for types: fn() -> R
/// factory_tuple! { A B C } // implements Handler for types: fn(A, B, C) -> R
/// ```
macro_rules! factory_tuple ({ $($param:ident)* } => {
impl<Func, Fut, $($param,)*> Handler<($($param,)*)> for Func
where
Func: Fn($($param),*) -> Fut + Clone + 'static,
Fut: Future,
{
type Output = Fut::Output;
type Future = Fut;
#[inline]
#[allow(non_snake_case)]
fn call(&self, ($($param,)*): ($($param,)*)) -> Self::Future {
(self)($($param,)*)
}
}
});
factory_tuple! {}
factory_tuple! { A }
factory_tuple! { A B }
factory_tuple! { A B C }
factory_tuple! { A B C D }
factory_tuple! { A B C D E }
factory_tuple! { A B C D E F }
factory_tuple! { A B C D E F G }
factory_tuple! { A B C D E F G H }
factory_tuple! { A B C D E F G H I }
factory_tuple! { A B C D E F G H I J }
factory_tuple! { A B C D E F G H I J K }
factory_tuple! { A B C D E F G H I J K L }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1994 次 |
| 最近记录: |