首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当将连接池传递给超级处理程序时,没有为闭包实现“特质core::ops::Fn<(请求,响应)”

当将连接池传递给超级处理程序时,没有为闭包实现“特质core::ops::Fn<(请求,响应)”
EN

Stack Overflow用户
提问于 2016-03-20 17:47:59
回答 1查看 137关注 0票数 1

我试图使用超高压r2d2在Rust中构建一个小型web服务,但我遇到了一些关于特性的问题。我无法解析编译器抛出的错误消息,所以我希望有人能帮助我。

考虑以下代码:

代码语言:javascript
复制
extern crate hyper;
extern crate postgres;
extern crate r2d2;
extern crate r2d2_postgres;

use hyper::Server;
use hyper::server::{Request,Response,Handler};
use r2d2_postgres::{SslMode, PostgresConnectionManager};
use r2d2::{Pool, PooledConnection};
use postgres::{Connection};

fn connect() -> Pool<PostgresConnectionManager>{
    let config = r2d2::Config::default();
    let conns = "postgres://abc:abc@localhost/abc";
    let manager = PostgresConnectionManager::new(conns, SslMode::None).unwrap();
    let pool = r2d2::Pool::new(config, manager).unwrap();
    return pool;
}

fn hello(pool: Pool<PostgresConnectionManager>, req: Request, res: Response) {
    res.send(b"Hello world").unwrap();
}

fn main() {
    let pool = connect();
    let dispatch = move |req: Request, res: Response| hello(pool, req, res);
    Server::http("127.0.0.1:3000").unwrap().handle(dispatch).unwrap();
}

我的目标是在函数pool中使用hello。通过使用闭包,我想,我可以传递一个环境变量wile,它仍然符合Hyper的期望。不幸的是,我得到了以下错误:

代码语言:javascript
复制
src/main.rs:28:45: 28:61 error: the trait `for<'r, 'r, 'r> core::ops::Fn<(hyper::server::request::Request<'r, 'r>, hyper::server::response::Response<'r>)>` is not implemented for the type `[closure@src/main.rs:27:20: 27:76 pool:r2d2::Pool<r2d2_postgres::PostgresConnectionManager>]` [E0277]
src/main.rs:28     Server::http("127.0.0.1:3000").unwrap().handle(dispatch).unwrap();
                                                           ^~~~~~~~~~~~~~~~
src/main.rs:28:45: 28:61 help: run `rustc --explain E0277` to see a detailed explanation
error: aborting due to previous error

这取决于pool的类型。例如,如果我试图传递一个i64,它会很好,编译器也不会抱怨。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-20 23:07:18

如果我们查看hyper的源代码,就可以看到所需的特性是为哪一个闭包实现的:

代码语言:javascript
复制
impl<F> Handler for F where F: Fn(Request, Response<Fresh>), F: Sync + Send {
    fn handle<'a, 'k>(&'a self, req: Request<'a, 'k>, res: Response<'a, Fresh>) {
        self(req, res)
    }
}

这意味着您的闭包需要实现Fn(Request, Response) + Sync + Send,以便为您实现Handler特性。否则,您需要自己实现它。由于闭包的值为pool,所以它只实现了FnOnce(Request, Response) (只能在pool被移到函数中时调用一次)。

要解决这个问题,请对池进行不可变的引用,这样您的函数就可以多次被调用(即实现Fn(Request, Response))。

代码语言:javascript
复制
fn hello(pool: &Pool<PostgresConnectionManager>, req: Request, res: Response) {
    res.send(b"Hello world").unwrap();
}

fn main() {
    let pool = connect();
    let dispatch = move |req: Request, res: Response| hello(&pool, req, res);
    Server::http("127.0.0.1:3000").unwrap().handle(dispatch).unwrap();
}

注意:性状Fn(Request, Response)是高级性状结合for<'r> Fn(Request<'r,'r>, Response<'r>)的句法糖.这是因为RequestResponse在一生中都是通用的,因此您的函数必须处理任何生命周期的Requests和Responses。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36117268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档