2017-03-09 66 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