Geschichte der Frage:
In Rust ist eine der häufig verwendeten Kollektionen die HashMap – ein assoziatives Array, das durch eine Hash-Tabelle implementiert wird. Das Besondere an der Rust-Implementierung ist die strikte Einhaltung der Besitz- und Speichersicherheitsregeln sowie Thread-Sicherheit nur unter bestimmten Bedingungen.
Problem:
Im Gegensatz zu anderen Sprachen mit Garbage Collection erfordern im Rust alle Operationen mit HashMap (Hinzufügen, Abrufen, Modifizieren) die Einhaltung der Besitzregeln. Beispielsweise kann die Kollektion nicht geändert werden, während aktive Verweise auf ihren Inhalt bestehen. Es stellt sich auch die Frage des Besitzes beim Einfügen: Elemente werden entweder verschoben oder kopiert. Bei gleichzeitigem Zugriff besteht das Risiko eines Datenrennens.
Lösung:
get_mut oder entry API.Beispielcode:
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")); }
Wichtige Merkmale:
get_mut darf die Struktur der Karte selbst nicht geändert werden (Schlüssel einfügen oder löschen).Kann es gleichzeitigen Zugriff auf mehrere Elemente der HashMap über verschiedene Verweise geben?
Nein, Rust erlaubt dies nicht über die Standard-API: Eine Iteration mit Änderung ist nur über einen exklusiven Verweis auf die gesamte HashMap möglich.
Was passiert, wenn man versucht, einen veränderlichen und unveränderlichen Verweis auf dasselbe Element zu erhalten?
Der Compiler gibt einen Fehler wegen der Verletzung der Regeln des Borrow Checkers aus: Ein veränderliches und unveränderliches Ausleihen desselben Wertes kann nicht gleichzeitig erfolgen.
Funktioniert die API entry() nur zum Einfügen neuer Elemente?
Nein, über die Entry-API kann man auch Zugriff zur Modifikation eines bestehenden Wertes erhalten, nicht nur zum Einfügen.
map.entry("key").and_modify(|v| *v += 1).or_insert(0);
Die Ausgabe von Verweisen auf Werte der HashMap in globale Variablen ohne Garantie der Lebensdauer der Karte.
Vorteile:
Nachteile:
Einwickeln der HashMap in Arc<Mutex<_>> zur Verwendung aus mehreren Threads.
Vorteile:
Nachteile: