一段 actix-web 中的示例代码
fn main() {
HttpServer::new(|| {
App::new()
.wrap_fn(|req, srv| { // 为什么这里不能用 wrap ?
println!("Hi from start. You request: {}", req.path());
srv.call(req).map(|res| {
println!("hi from response");
res
})
})
.service(web::resource("/index").to(|| {
println!("hello in handler");
"hello middleware"
}))
})
.bind("127.0.0.1:8080")
.unwrap()
.run()
.unwrap();
}
问题一:为什么上面的 wrap_fn
不能换成 wrap
, 因为我看到 warp_fn
中也是直接调用 wrap 函数的,为什么这里就不行了呢
// wrap_fn 的代码
pub fn wrap_fn<B1, F, R>(
self,
mw: F,
) -> App<
impl NewService<
Config = (),
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1,
>
where
B1: MessageBody,
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
R: IntoFuture<Item = ServiceResponse<B1>, Error = Error>,
{
self.wrap(mw)
}
// wrap 的代码
pub fn wrap<M, B1, F>(
self,
mw: F,
) -> App<
impl NewService<
Config = (),
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1,
>
where
M: Transform<
T::Service,
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1: MessageBody,
F: IntoTransform<M, T::Service>,
{
let endpoint = apply_transform(mw, self.endpoint);
App {
endpoint,
data: self.data,
data_factories: self.data_factories,
services: self.services,
default: self.default,
factory_ref: self.factory_ref,
config: self.config,
external: self.external,
_t: PhantomData,
}
}
问题二: 把上面闭包函数体中的内容提取出来,写成下面这样为什么是错的呢?
fn main() {
// 闭包体提取出来
let app = App::new()
.wrap_fn(|req, srv| {
println!("Hi from start. You request: {}", req.path());
srv.call(req).map(|res| {
println!("hi from response");
res
})
})
.service(web::resource("/index").to(|| {
println!("hello in handler");
"hello middleware"
}));
HttpServer::new(|| app)
.bind("127.0.0.1:8080")
.unwrap()
.run()
.unwrap();
}
这两个应该是一个类型的问题吧--
请各位大大能耐心解答下,给个相关的链接也可以,谢谢!!
1
共 1 条评论, 1 页
评论区
写评论粗略回答, 第一个问题: wrap 和 wrap_fn 参数约束不一样。 where 表明了各自的参数约束,wrap 的F要实现特征IntoTransfrom,而wrap_fn的F要实现特征IntoFuture。
第二个问题: HttpServer要求F 有Send特性, 而App 是!Send特性。 把App放在闭包外这肯定不行。闭包是通过引用获取变量。
说白了,就是HttpServer是多线程的,App是不能被多线程共享的