Skip to content

Instantly share code, notes, and snippets.

@mcpar-land
Last active May 23, 2022 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcpar-land/ce6fc045778012b7140a891040f525bc to your computer and use it in GitHub Desktop.
Save mcpar-land/ce6fc045778012b7140a891040f525bc to your computer and use it in GitHub Desktop.
Golang 1.18 undo example
package main
import (
"fmt"
)
func main() {
fmt.Print("Hello, ", "playground\n")
s := AppState{}
a := ActionStack[AppState]{}
fmt.Printf("%#v\n", s)
a.ApplyDo(ChangeCountAction{amount: 2}, &s)
fmt.Printf("%#v\n", s)
a.ApplyDo(ChangeBirthdayAction(true), &s)
fmt.Printf("%#v\n", s)
a.ApplyUndo(&s)
fmt.Printf("%#v\n", s)
a.ApplyUndo(&s)
fmt.Printf("%#v\n", s)
a.ApplyUndo(&s)
fmt.Printf("%#v\n", s)
}
type ActionStack[T any] struct {
stack []Action[T]
}
func (a *ActionStack[T]) ApplyDo(action Action[T], state *T) {
a.stack = append(a.stack, action)
action.Do(state)
}
func (a *ActionStack[T]) ApplyUndo(state *T) {
l := len(a.stack)
if l == 0 {
return
}
last := a.stack[l-1]
a.stack = a.stack[:l-1]
last.Undo(state)
}
type Action[T any] interface {
Do(*T)
Undo(*T)
}
type AppState struct {
count int
isBirthday bool
}
type ChangeCountAction struct {
amount int
}
func (c ChangeCountAction) Do(state *AppState) {
state.count += c.amount
}
func (c ChangeCountAction) Undo(state *AppState) {
state.count -= c.amount
}
type ChangeBirthdayAction bool
func (c ChangeBirthdayAction) Do(state *AppState) {
state.isBirthday = bool(c)
}
func (c ChangeBirthdayAction) Undo(state *AppState) {
state.isBirthday = !bool(c)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment