rust / intermediate
Snippet
Assoziierte Typen in Traits
Assoziierte Typen definieren Platzhalter-Typen in Traits, die implementierende Typen spezifizieren müssen. Im Gegensatz zu generischen Trait-Parametern stellen assoziierte Typen sicher, dass nur eine Implementierung pro Typ existiert, was mehrdeutige Methodenaufrufe verhindert. Sie sind ideal, wenn jeder Implementierer genau einen konkreten Typ für die Beziehung benötigt—dies ermöglicht sauberere Methodensignaturen und erlaubt dem Compiler Typen zu inferieren. Die where-Klausel schränkt weiter ein, dass der Item-Typ Debug implementieren muss.
snippet.rs
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
trait Graph<N, E> {fn edges_between(&self, n1: &N, n2: &N) -> Option<&E>;}trait Container {type Item;fn add(&mut self, item: Self::Item);fn get(&self, index: usize) -> Option<&Self::Item>;}struct Stack<T> {items: Vec<T>,}impl<T> Container for Stack<T> {type Item = T;fn add(&mut self, item: T) { self.items.push(item); }fn get(&self, index: usize) -> Option<&T> { self.items.get(index) }}trait Serializable {type Output: std::fmt::Display;fn serialize(&self) -> Self::Output;}impl Serializable for i32 {type Output = String;fn serialize(&self) -> String { format!("i32:{}", self) }}impl Serializable for String {type Output = String;fn serialize(&self) -> String { format!("str:{}", self) }}fn process<C: Container>(container: &C) -> usizewhere C::Item: std::fmt::Debug {container.get(0).map(|i| println!("First: {:?}", i));42}
Erklärung
1
type Item;
Platzhalter-Typ in Trait-Definition deklariert
2
type Item = T;
Konkreter Typ in Implementierung bereitgestellt
3
Self::Item
Referenz auf assoziierten Typ in Trait-Methoden
4
C::Item: Debug
Where-Klausel schränkt assoziierten Typ indirekt ein
5
Container<Item = T>
Vollständige Qualifikation der Assoziationstyp-Bindung