2015-05-31 13 views
8

Questo è il mio primo giorno con Rust, ma sto cercando di fare qualcosa di banale, e sono bloccato.Impossibile prendere in prestito la variabile esterna catturata in una chiusura `Fn` come mutabile

Quello che sto cercando di fare è aggiungere una struttura a un vettore e restituire il risultato. Quello che sto cercando è di creare un servizio REST molto semplice che memorizzerà i dati in memoria durante la pubblicazione e restituirà tutti i dati in formato JSON quando si esegue un GET.

Questo è il mio codice corrente:

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

ho cercato this solution con un RefCell, ma poi ho l'errore che il tratto di sincronizzazione non è implementata per Vec<reservation::Reservation>

risposta

13

Questo è un ottimo esempio di come Rust ti protegge dalla mancanza di filo.

Se ci pensate, nel vostro codice corrente sarebbe possibile che più thread provino a mutare contemporaneamente reservations senza alcun tipo di sincronizzazione. Questa è una corsa di dati e Rust si lamenterà di ciò.

Una possibile soluzione sarebbe quella di avvolgere il vettore reservations in un Mutex per ottenere la sincronizzazione. Avrai anche bisogno di un Arc (conteggio dei riferimenti atomici), poiché Rust non può dimostrare che reservations vivrà più a lungo dei thread.

Con queste modifiche, il codice dovrebbe essere simile al seguente:

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

È possibile controllare la documentazione per informazioni aggiuntive su Mutex e Arc.

Problemi correlati