2015-05-31 46 views
8

這是我第一天與Rust,但我試圖做一些微不足道的事情,而且我被卡住了。不能在'Fn`閉包中借用捕獲的外部變量作爲可變

我想要做的是將一個結構添加到向量,並返回結果。我正在嘗試創建一個非常簡單的REST服務,它將在發佈時將數據存儲在內存中,並在執行GET時返回JSON格式的所有數據。

這是我當前的代碼:

fn main() { 
    let mut server = Nickel::new(); 
    let mut reservations = Vec::new(); 

    server.post("/reservations/", middleware! { |request, response| 
     let reservation = request.json_as::<Reservation>().unwrap(); 

     reservations.push(reservation); // <-- error occurs here 

     format!("Hello {} {}", reservation.name, reservation.email) 

    }); 

    server.listen("127.0.0.1:3000"); 
} 

我試圖this solution有RefCell,但後來我得到性狀的同步還沒有爲Vec<reservation::Reservation>

回答

13

執行的錯誤這是一個很好的例子Rust如何保護您不受線程不安全的影響。

如果你想一想,在你當前的代碼中,多線程可能會嘗試同步變異reservations而沒有任何類型的同步。這是一場數據競賽,Rust會對此抱怨。

一個可能的解決方案是將reservations向量換成Mutex以獲得同步。您還需要Arc(原子參考計數),因爲Rust無法證明reservations的壽命比線程長。

有了這些變化,你的代碼應該是這樣的:

use std::sync::{Arc, Mutex}; 
fn main() { 
    let mut server = Nickel::new(); 
    let reservations = Arc::new(Mutex::new(Vec::new())); 

    server.post("/reservations/", middleware! { |request, response| 
     let reservation = request.json_as::<Reservation>().unwrap(); 

     reservations.lock().unwrap().push(reservation); // <-- error occurs here 

     format!("Hello {} {}", reservation.name, reservation.email) 

    }); 

    server.listen("127.0.0.1:3000"); 
} 

您可以檢查,瞭解更多信息有關MutexArc的文檔。

相關問題