具有包含异步块的闭包的异步方法无法推断适当的生存期

问题描述 投票:0回答:1

我正在尝试使用hyper创建小型HTTP路由器,但是启动服务器时遇到了一些困难。

以下功能是我遇到麻烦的地方。

依赖关系:

[dependencies]
hyper = "0.13"
tokio = { version = "0.2", features = ["full"] }
use std::net::SocketAddr;
use std::convert::Infallible;
use hyper::Server;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response};

#[tokio::main]
async fn main() {
    let router = Router::new(SocketAddr::from(([127, 0, 0, 1], 80)));
    router.start();
}

pub struct Router<'a> {
    addr: SocketAddr,
}

impl<'a> Router<'a> {
    pub fn new(addr: SocketAddr) -> Self {
        Self {
            addr,
        }
    }

    pub async fn start(&self) {
        let make_svc = make_service_fn(|_| async {
            Ok::<_, Infallible>(service_fn(|req| self.route(req)))
        });

        let server = Server::bind(&self.addr).serve(make_svc);

        println!("Listening on http://{}", self.addr);

        if let Err(e) = server.await {
            eprintln!("Server error: {}", e);
        }
    }

    pub async fn route(&self, req: Request<Body>) -> Result<Response<Body>, Infallible> {
        // TODO

        Ok(Response::new(
            "Hello, world!".into()
        ))
    }
}

我不能使用Ok::<_, Infallible>(service_fn(self.route),因为参数之一是&self。我发现的解决方案的问题是编译器无法推断出适当的生存期,而且我也不知道如何解决它。

error: cannot infer an appropriate lifetime
  --> src\main.rs:24:24
   |
24 |     pub async fn start(&self) {
   |                        ^^^^^ ...but this borrow...
...
29 |         let server = Server::bind(&self.addr).serve(make_svc);
   |                                               ----- this return type evaluates to the `'static` lifetime...
   |
note: ...can't outlive the lifetime `'_` as defined on the method body at 24:24
  --> src\main.rs:24:24
   |
24 |     pub async fn start(&self) {
   |                        ^

error: aborting due to previous error
rust closures lifetime hyper
1个回答
0
投票

您的make_svc使用&self,但是仅在start函数结束之前临时借用该变量。服务器可能在start函数外部,因此无法在其中引用借用的变量。]​​>

当对诸如服务器之类的长期使用闭包时,不能使用临时引用。改用Arc,例如start(self: Arc<Self>)并实际上在调用该方法之前将该对象包装在Arc::new()中。

© www.soinside.com 2019 - 2024. All rights reserved.