2015-05-31 10 views
8

To jest mój pierwszy dzień z Rust, ale próbuję zrobić coś trywialnego i utknąłem.Nie mogę pożyczyć przechwyconej zmiennej zewnętrznej w zamknięciu `Fn jako zmiennym

Co próbuję zrobić, to dodać struct do Vector i zwrócić wynik. Próbuję utworzyć bardzo prostą usługę REST, która będzie przechowywać dane w pamięci podczas publikowania i zwracać wszystkie dane w formacie JSON podczas wykonywania polecenia GET.

To jest mój bieżący kod:

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"); 
} 

Próbowałem this solution z RefCell, ale wtedy pojawia się błąd, że cecha Sync nie jest realizowany za Vec<reservation::Reservation>

Odpowiedz

13

To jest bardzo dobry przykład w jaki sposób Rust chroni Cię przed zagrożeniami związanymi z gwintem.

Jeśli się nad tym zastanowisz, w twoim obecnym kodzie byłoby możliwe, że wiele wątków spróbuje jednocześnie zmutować numer reservations bez jakiejkolwiek synchronizacji. To wyścig danych i Rust narzeka na to.

Możliwe rozwiązanie polega na owinięciu wektora reservations do Mutex, aby uzyskać synchronizację. Będziesz także potrzebował Arc (liczenie odniesień atomowych), ponieważ Rust nie może dowieść, że reservations będzie żył dłużej niż wątki.

Z tych zmian, kod powinien być jak następuje:

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"); 
} 

Można sprawdzić dokumentację dodatkową informacją o Mutex i Arc.

Powiązane problemy