capypad
0 Tage Serie
rust / intermediate
Snippet

HashMap mit benutzerdefinierten Schlüsseltypen: Eq und Hash implementieren

Um einen benutzerdefinierten Typ als HashMap-Schlüssel zu verwenden, müssen Sie drei Traits implementieren: PartialEq für Gleichheitsvergleich, Eq um transitive Gleichheit zu garantieren (erforderlich wenn PartialEq implementiert ist), und Hash um einen Hash-Wert für den Hasher zu generieren. Der Hash sollte alle Felder kombinieren, die in die Gleichheit einfließen—wenn zwei Person-Strukturen gleich sind, müssen sie denselben Hash erzeugen. Dieses Muster ermöglicht struktur-basierte Schlüssel statt nur primitiver Typen.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::fmt;
 
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
 
impl PartialEq for Person {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.age == other.age
}
}
 
impl Eq for Person {}
 
impl Hash for Person {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.age.hash(state);
}
}
 
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} ({})", self.name, self.age)
}
}
 
fn main() {
let mut people: HashMap<Person, &str> = HashMap::new();
let alice = Person { name: String::from("Alice"), age: 30 };
let bob = Person { name: String::from("Bob"), age: 25 };
people.insert(alice, "Engineer");
people.insert(bob, "Designer");
let lookup = Person { name: String::from("Alice"), age: 30 };
if let Some(&profession) = people.get(&lookup) {
println!("Alice is an {}", profession);
}
println!("Total people: {}", people.len());
}
Erklärung
1
impl PartialEq for Person {
Definiert Gleichheit basierend auf sowohl name als auch age Feldern
2
impl Eq for Person {}
Eq ist ein Marker-Trait, das keine NaN-ähnlichen Randfälle Assertiert
3
self.name.hash(state); self.age.hash(state);
Beide Felder tragen zum Hash bei—Reihenfolge ist wichtig für Konsistenz
4
people.get(&lookup)
Eine neue Person mit denselben Werten findet erfolgreich den Eintrag