1

我正在尝试用闭包声明我的路线:

use mongodb::Client;

pub fn get_user_routes(client: Client) -> Router {
    let controller = controller::UserController::new(client);
    let handler = handlers::UserHandler::new(controller);

    router!(
         index:  get    "/"    => move |r: &mut Request| handler.index(r),
         show:   get    "/:id" => move |r: &mut Request| handler.show(r),
    )
}

我收到此错误,我无法Copy为我实现该特征,UserController因为mongodb::Client它没有实现它(它是一个Arc)。

error[E0382]: capture of moved value: `handler`
      --> src/api/users/mod.rs:17:57
       |
    16 |         index:  get    "/"    => move |r: &mut Request| handler.index(r),
       |                                  ---------------------- value moved (into closure) here
    17 |         show:   get    "/:id" => move |r: &mut Request| handler.show(r),
       |                                                         ^^^^^^^ value captured here after move
       |
       = note: move occurs because `handler` has type `api::users::handlers::UserHandler`, which does not implement the `Copy` trait

UserHandler只有一个UserController和一个UserController,一个mongodb::Client

4

2 回答 2

3

routerget方法通过value获取处理程序。在 Rust 中,按值传递意味着放弃所有权。

根据定义,您不能两次放弃某物的所有权:第一次放弃后,它就不再属于您了!该规则的唯一例外是Copy类型,但它们仅限于整数和非变异引用(并且引用已被淘汰,因为Handler: 'static)。

因此,您需要调用.clone()要传递的处理程序。每次。

一个非常简单的方法是使用块表达式:

let h  = handler;
router!(
    index: get "/"    => { let h = h.clone(); move |r: &mut Request| h.index(r) },
    show:  get "/:id" => { let h = h.clone(); move |r: &mut Request| h.show(r) },
)

这样,您不必事先声明所有克隆。

于 2017-03-10T11:50:47.850 回答
1

您可以#[derive(Clone)]为您的处理程序,并克隆它:

let handler_show = handler.clone();
router!(
     index:  get    "/"    => move |r: &mut Request| handler.index(r),
     show:   get    "/:id" => move |r: &mut Request| handler_show.show(r),
)
于 2017-03-10T02:45:34.297 回答