使用 hyper 闭包的 Rust 生命周期
Rust lifetimes with closures using hyper
一直在学习 Rust,在将 conn
传递给 request_handler
时遇到了生命周期问题。我收到一条错误消息
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/main.rs:33:70
|
33 | let request_handler = |req: Request<Body>| async { request_handler(conn, req).await };
| ^^^^
|
= note: ...the reference is valid for the static lifetime...
但我不确定如何使用闭包处理生命周期并且 why/how 它是静态的。我对生命周期和借贷的理解很松散,但这似乎是一个更复杂的案例。我也不会使用闭包,但是其中一个闭包的 return 类型有一个 hyper crate 没有导出的类型,所以我不知道如何创建 fn
无法声明 return 类型。
我还可以确认是否删除传递 conn
我可以让一切正常工作,但我想在 request_handler
.
中使用 conn
对象
use hyper::server::conn::AddrStream;
use hyper::service::make_service_fn;
use hyper::Version;
use hyper::{Body, Error, Method, Request, Response, Server};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
mod http_models;
mod utils;
use hyper::service::service_fn;
async fn request_handler(
conn: &'static AddrStream,
req: Request<Body>,
) -> Result<Response<Body>, hyper::Error> {
println!("req: {:?}", req);
if req.method() == Method::CONNECT {
println!("Connect")
}
let res: Response<Body> = Response::builder()
.status(200)
.version(Version::HTTP_11)
.body(Body::empty())
.unwrap();
return Ok(res);
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let addr = SocketAddr::new(ip, 1337);
//let client = Client::new();
let make_service = make_service_fn(|conn: &AddrStream| async {
let request_handler = |req: Request<Body>| async { request_handler(conn, req).await };
let service = service_fn(request_handler);
Ok::<_, Error>(service)
});
let server = Server::bind(&addr).serve(make_service);
println!("Listening on http://{}", addr);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}
传递给 make_service_fn
的闭包的 conn
参数仅与闭包主体一样长,但闭包的 return 值 (Ok(service)
) 引用它。闭包 must have the type FnMut(&Target) -> impl Future
,这意味着遗憾的是它不允许 return 引用其参数的值。
唯一的解决方案是 copy/clone 在设置请求处理程序时从 conn
获取任何你需要的东西,因为一旦闭包 returns 你就无法保留对它的引用。
一直在学习 Rust,在将 conn
传递给 request_handler
时遇到了生命周期问题。我收到一条错误消息
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/main.rs:33:70
|
33 | let request_handler = |req: Request<Body>| async { request_handler(conn, req).await };
| ^^^^
|
= note: ...the reference is valid for the static lifetime...
但我不确定如何使用闭包处理生命周期并且 why/how 它是静态的。我对生命周期和借贷的理解很松散,但这似乎是一个更复杂的案例。我也不会使用闭包,但是其中一个闭包的 return 类型有一个 hyper crate 没有导出的类型,所以我不知道如何创建 fn
无法声明 return 类型。
我还可以确认是否删除传递 conn
我可以让一切正常工作,但我想在 request_handler
.
conn
对象
use hyper::server::conn::AddrStream;
use hyper::service::make_service_fn;
use hyper::Version;
use hyper::{Body, Error, Method, Request, Response, Server};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
mod http_models;
mod utils;
use hyper::service::service_fn;
async fn request_handler(
conn: &'static AddrStream,
req: Request<Body>,
) -> Result<Response<Body>, hyper::Error> {
println!("req: {:?}", req);
if req.method() == Method::CONNECT {
println!("Connect")
}
let res: Response<Body> = Response::builder()
.status(200)
.version(Version::HTTP_11)
.body(Body::empty())
.unwrap();
return Ok(res);
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let addr = SocketAddr::new(ip, 1337);
//let client = Client::new();
let make_service = make_service_fn(|conn: &AddrStream| async {
let request_handler = |req: Request<Body>| async { request_handler(conn, req).await };
let service = service_fn(request_handler);
Ok::<_, Error>(service)
});
let server = Server::bind(&addr).serve(make_service);
println!("Listening on http://{}", addr);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}
传递给 make_service_fn
的闭包的 conn
参数仅与闭包主体一样长,但闭包的 return 值 (Ok(service)
) 引用它。闭包 must have the type FnMut(&Target) -> impl Future
,这意味着遗憾的是它不允许 return 引用其参数的值。
唯一的解决方案是 copy/clone 在设置请求处理程序时从 conn
获取任何你需要的东西,因为一旦闭包 returns 你就无法保留对它的引用。