capypad
0 Tage Serie
rust / expert
Snippet

Zero-Cost Typestate-Pattern mit PhantomData

Das Typestate-Pattern nutzt Rusts Typsystem, um Zustandsübergänge zur Kompilierzeit zu erzwingen. Durch die Verwendung von PhantomData können wir Zustände unterscheiden, ohne Laufzeit-Speicher-Overhead zu verursachen. Dies stellt sicher, dass Methoden wie 'process' nur aufgerufen werden können, wenn die Daten den Zustand 'Checked' erreicht haben.

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
use std::marker::PhantomData;
 
struct Unchecked;
struct Checked;
 
struct Data<S> {
value: String,
_state: PhantomData<S>,
}
 
impl Data<Unchecked> {
fn new(v: &str) -> Self {
Data { value: v.into(), _state: PhantomData }
}
fn validate(self) -> Data<Checked> {
// Perform complex validation logic here
Data { value: self.value, _state: PhantomData }
}
}
 
impl Data<Checked> {
fn process(&self) {
println!("Processing validated data: {}", self.value);
}
}
Erklärung
1
struct Unchecked;
Ein Marker-Typ der Größe Null, der den Initialzustand darstellt.
2
_state: PhantomData<S>,
Informiert den Compiler, dass Data logisch den Typ S besitzt, ohne ihn physisch zu speichern.
3
fn validate(self) -> Data<Checked>
Konsumiert den aktuellen Zustand und gibt einen neuen Zustand zurück, wodurch der alte unzugänglich wird.