2017-03-09 64 views
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只是有一个UserControllerUserController,一个mongodb::Client

回答

3

路由器get方法,通过需要处理。在鲁斯特里,传递价值意味着放弃所有权。

根据定义,你不能放弃两次所有权:在第一次放弃之后,它不再是你的!该规则的唯一例外是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) }, 
) 

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

+0

您保存了我的重构! – NotBad4U

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), 
) 
+0

感谢您的回应,但不幸的是我将来会有超过2条路线,我认为这不是一个优雅的解决方案,为每条新路线创建一个变量。 – NotBad4U