Storia della domanda:
In Rust, una delle collezioni più utilizzate è HashMap — un array associativo implementato come tabella hash. La differenza rispetto all'implementazione in altri linguaggi è il rigido rispetto delle regole di proprietà e della sicurezza della memoria, oltre alla sicurezza dei thread solo in determinate condizioni.
Problema:
A differenza di altri linguaggi con garbage collection, in Rust qualsiasi operazione con HashMap (aggiunta, estrazione, modifica) richiede di rispettare le regole di proprietà. Ad esempio, non è possibile modificare la collezione mantenendo riferimenti attivi al suo contenuto. Si pone anche la questione della proprietà durante l'inserimento: gli elementi vengono spostati o clonati. Inoltre, nell'accesso concorrente esiste il rischio di data race.
Soluzione:
get_mut o entry.Esempio di codice:
use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert("key", 10); if let Some(value) = map.get_mut("key") { *value += 1; } println!("{:?}", map.get("key")); }
Caratteristiche chiave:
Può esserci accesso simultaneo a più elementi di HashMap tramite diversi riferimenti?
No, Rust non lo consente tramite l'API standard: l'iterazione con modifica è possibile solo tramite un riferimento esclusivo all'intero HashMap.
Cosa succede se si cerca di ottenere un riferimento mutabile e non mutabile allo stesso elemento?
Il compilatore genererà un errore per violazione delle regole del borrow checker: non è possibile combinare il borrowing mutabile e non mutabile di uno stesso valore.
L'API entry() funziona solo per l'inserimento di nuovi elementi?
No, tramite l'API Entry è possibile anche accedere per modificare un valore esistente, non solo per l'inserimento.
map.entry("key").and_modify(|v| *v += 1).or_insert(0);
Erogazione di riferimenti ai valori di HashMap a variabili globali senza garanzia di lifetime della mappa.
Pro:
Contro:
Imballare HashMap in Arc<Mutex<_>> per utilizzo da più thread.
Pro:
Contro: