< 返回版块

king-etc 发表于 2020-05-26 17:52

各位我刚开始接触rust 现在遇到一些问题想求助各位 我想创建一个类用来处理POST请求,但是无法编译,错误信息如下,源码也在下面。 期待各位的解答。谢谢

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src\main.rs:69:21
   |
69 |                 tom.call(req)
   |                     ^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 68:44...
  --> src\main.rs:68:44
   |
68 |             Ok::<_, Infallible>(service_fn(move |req| {
   |                                            ^^^^^^^^^^
note: ...so that closure can access `tom`
  --> src\main.rs:69:17
   |
69 |                 tom.call(req)
   |                 ^^^
note: but, the lifetime must be valid for the expression at 68:33...
  --> src\main.rs:68:33
   |
68 |             Ok::<_, Infallible>(service_fn(move |req| {
   |                                 ^^^^^^^^^^
note: ...so type `fn([closure@src\main.rs:68:44: 70:14 tom:std::sync::Arc<Host>]) -> hyper::service::util::ServiceFn<[closure@src\main.rs:68:44: 70:14 tom:std::sync::Arc<Host>], hyper::body::body::Body> {hyper::service::util::service_fn::<[closure@src\main.rs:68:44: 70:14 tom:std::sync::Arc<Host>], hyper::body::body::Body, impl std::future::Future>}` of expression is valid during the expression
  --> src\main.rs:68:33
   |
68 |             Ok::<_, Infallible>(service_fn(move |req| {
   |                                 ^^^^^^^^^^

error: aborting due to previous error
use std::error::Error;
use std::convert::Infallible;
use std::sync::{Arc};
use hyper::service::{make_service_fn, service_fn};
use futures_util::{future, TryStreamExt};
use hyper::{header, Body, Client, Method, Request, Response, Server, StatusCode};

struct Host {
    name:String,
    num:u64,
}

impl Host
{
    pub fn new(name: String, num: u64) -> Self 
    {
        Self
        {
            name,
            num,
        }
    }
    pub async fn call(&self ,req: Request<Body>) -> Result<Response<Body>, hyper::Error>
    {
        let mut response = Response::new(Body::empty());
        match (req.method(), req.uri().path()) 
        {
            (&Method::POST, "/") => 
            {
                let (parts, body) = req.into_parts();
                let entire_body = body
                .try_fold(Vec::new(), |mut data, chunk| async move {
                    data.extend_from_slice(&chunk);
                    Ok(data)
                })
                .await?;
                let x = String::from_utf8(entire_body).unwrap();
                Ok(Response::new(Body::from(x)))
            }
            _ => 
            {
                let mut not_found = Response::default();
                *not_found.status_mut() = StatusCode::NOT_FOUND;
                Ok(not_found)
            }
        }
    }
}

#[tokio::main]
async fn main() {
    let addr = ([127, 0, 0, 1], 3000).into();
    let example = Arc::new(Host::new("tom".to_string(),123));
    let make_service = make_service_fn(move |_| {
        let tom = example.clone();
        async move { 
            Ok::<_, Infallible>(service_fn(move |req| {
                tom.call(req)
            }))
        }
    });
    let server = Server::bind(&addr).serve(make_service);
    if let Err(e) = server.await {
        eprintln!("server error: {}", e);
    }
}

评论区

写评论
TOETOE55 2020-05-26 19:09

把call改成这样就好了。

pub fn call(&self ,req: Request<Body>) 
    -> impl Future<Output = Result<Response<Body>, hyper::Error>>

如果用async fn的话,相当于:

pub fn call<'a>(&'a self ,req: Request<Body>) 
    -> impl Future<Output = Result<Response<Body>, hyper::Error>> + 'a

多了这个约束,就不能从

move |req| {
    tom.call(req)
}

中返回了,因为rust把你当成返回局部变量的引用了

1 共 1 条评论, 1 页