Ho un RefCell<HashMap>
e vogliono prendere in prestito il tavolo, trovare una chiave, e restituire un riferimento al risultato:restituendo il T preso in prestito da RefCell <T>
struct Frame {
map: RefCell<HashMap<String, String>>
}
impl Frame {
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
// Borrow checker barfs here!
self.map.borrow().get(k)
//^~~~~~~~~~~~~~~ borrowed value does not live long enough
}
}
(playpen)
Se rimuovo la roba RefCell
poi tutto funziona bene:
struct Frame {
map: HashMap<String, String>
}
impl Frame {
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
self.map.get(k)
}
}
Qual è il modo corretto di scrivere la funzione di ricerca senza copiare ° e stringa nella tabella hash?
Ehi, grazie. Questa è una grande spiegazione. Sto ancora imparando, quindi ho lottato con il controllore del prestito, ma ovviamente questo ha senso. Suppongo che non capisco perché il RefCell fa la differenza - perché la versione non RefCell causa anche problemi per lo stesso motivo? –
@MarcMiller: Suppongo che ormai ti rendi conto che Rust è interamente basato sulla proprietà e sul prestito. Normalmente, questi vengono controllati in fase di compilazione, tuttavia esistono costrutti basati su codice 'non sicuro 'che si trovano nel compilatore e invece verificano la correttezza in fase di esecuzione. 'RefCell' è un tale costrutto, e quindi introducendolo cambia leggermente le regole; puoi pensarlo come un mutex di lettura-scrittura per il codice a thread singolo. –
@ matthieu-m: Grazie per aver fatto un salto! Potrei disturbarti a chiarire? Stai dicendo che RefCell lo cambia in una sorta di blocco del writer invece di un semplice lock del lettore, anche se non sto facendo borrow_mut? Non voglio davvero clonare i miei valori di ritorno qui dato che i miei oggetti possono essere abbastanza grandi, quindi sto cercando di fare qualcosa come ref-counting: RefCell> - ma mi fa sentire come se stessi facendo qualcosa di sbagliato. Grazie. –