【问题标题】:how to use methods of struct as handlers in rocket如何在火箭中使用结构的方法作为处理程序
【发布时间】:2023-03-06 21:23:01
【问题描述】:
#[derive(Debug, Clone)]
struct Author<T: Persister + Send + Sync + Clone> {
    dao: T,
}

impl<T: Persister + Send + Sync + Clone> Author<T> {
    fn new(dao: T) -> Self {
        Author { dao: dao }
    }
    fn handle_sign_up<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
        Outcome::Success(Response::new())
    }
}

impl<T> Handler for Author<T>
where
    T: Persister + Send + Sync + Clone + 'static,
{
    fn handle<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
        Outcome::Success(Response::new())
    }
}

impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
    fn into(self) -> Vec<Route> {
        vec![Route::new(rocket::http::Method::Post, "/", self)]
    }
}

fn main() {
    let dao = Dao::new("mysql://user:password@localhost/test".to_owned()).unwrap();
    let author = Author::new(dao);
    rocket::ignite().mount("/", author).launch();
}

我想使用Author(例如Author::handle_sign_up)的方法作为路由的处理程序,但它不起作用。我尝试使用如下所示的clouser

impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
    fn into(self) -> Vec<Route> {
        let p = |req, data| self.handle_sign_up(req, data);
        vec![Route::new(rocket::http::Method::Post, "/", p)]
    }
}

,编译器报告了一个生命周期错误

类型不匹配 预期类型for&lt;'r, 's&gt; Fn&lt;(&amp;'r rocket::Request&lt;'s&gt;, rocket::Data)&gt; 找到类型Fn&lt;(&amp;rocket::Request&lt;'_&gt;, rocket::Data)&gt;

有什么方法可以实现吗?

【问题讨论】:

    标签: rust rust-rocket


    【解决方案1】:

    |req, data| self.handle_sign_up(req, data) 的问题在于,编译器会推断参数类型的生命周期,但在这里会出错。 &amp;'r RequestOutcome&lt;'r&gt;之间的关系是必需的,缺少的。

    很遗憾,you cannot explicitly annotate the lifetimes of a closure

    一种解决方法(如上面链接中的一个答案所建议的)是使用辅助函数,它不做任何事情,但鼓励编译器推断正确的签名:

    fn as_handler_func<F>(f: F) -> F
    where
        F: for<'r> Fn(&'r Request, Data) -> Outcome<'r>,
    {
        f
    }
    
    impl<T: Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
        fn into(self) -> Vec<Route> {
            let p = as_handler_fn(move |req, data| self.handle_sign_up(req, data));
            vec![Route::new(rocket::http::Method::Post, "/", p)]
        }
    }
    

    附带说明:我不是 Rocket 方面的专家,但我相信如果您像这样为 Author 实施 Into&lt;Vec&lt;Route&gt;&gt;,您可能也不想为它使用 impl Handler

    【讨论】:

      猜你喜欢
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 2017-09-29
      • 2013-06-26
      • 1970-01-01
      相关资源
      最近更新 更多