857 B
857 B
Typestate Pattern in Go: Separate Structs
In Go, we can implement the typestate pattern similarly to the Rust "Builder Pattern" solution by using separate structs for each state.
pwLocked := NewCredentialManager()
pwUnlocked := pwLocked.Unlock("pssst")
pwUnlocked.Set("foo", "bar")
_, _ = pwUnlocked.Get("foo")
pwUnlocked.Lock()
By returning a different struct type from Unlock and Lock, we can control which methods are available on the returned object.
Caveats
Unlike Rust, Go does not have an ownership model. This means that the original object (e.g., pwLocked) remains valid and usable even after it has been "moved" to a new state. This can lead to logic errors if the old object is reused.
pwLocked := NewCredentialManager()
pwUnlocked := pwLocked.Unlock("pssst")
pwLocked.Unlock("pssst") // Still possible! 💥