rust / expert
Snippet
Erzwingen von Zustandsmaschinen-Invarianten zur Kompilierzeit mittels PhantomData
Das Type-State-Pattern nutzt das Typsystem von Rust, um gültige Übergänge in einer Zustandsmaschine zur Kompilierzeit zu erzwingen. Durch die Verwendung generischer Parameter, die den Zustand darstellen, und PhantomData, um den Compiler ohne Laufzeit-Overhead zufriedenzustellen, verhindern wir, dass ungültige Operationen (wie das Anzeigen eines unveröffentlichten Beitrags) überhaupt kompiliert werden.
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
use std::marker::PhantomData;pub struct Draft;pub struct Published;pub struct Post<State> {content: String,_state: PhantomData<State>,}impl Post<Draft> {pub fn new(content: String) -> Self {Post { content, _state: PhantomData }}pub fn publish(self) -> Post<Published> {Post { content: self.content, _state: PhantomData }}}impl Post<Published> {pub fn view(&self) -> &str {&self.content}}
Erklärung
1
pub struct Post<State> {
Deklariert ein generisches Struct, bei dem State als Typ-Marker dient, der die aktuelle Lebenszyklusphase des Beitrags darstellt.
2
_state: PhantomData<State>,
Weist den Compiler an, dass sich Post so verhält, als würde es einen Wert vom Typ State besitzen, wodurch Fehler wegen ungenutzter Typparameter verhindert werden, ohne Laufzeitspeicher zu belegen.
3
impl Post<Draft> {
Implementiert Methoden, die ausschließlich verfügbar sind, wenn sich der Post im Zustand Draft befindet.
4
pub fn publish(self) -> Post<Published> {
Konsumiert den Entwurf-Beitrag und gibt einen neuen Beitrag zurück, der mit dem Zustand Published markiert ist, wodurch weitere Zustandsänderungen verhindert werden.