zoukankan      html  css  js  c++  java
  • 一个undo的实现

    委托机制

    package main
    
    import (
        "errors"
        "fmt"
        "sort"
        "strings"
    )
    
    type InSet struct {
        data map[int]bool
        undo Undo
    }
    
    type UndoableInSet struct {
        InSet
        functions []func()
    }
    
    func NewUndoableInSet() UndoableInSet {
        return UndoableInSet{NewInSet(), nil}
    }
    
    func (set *UndoableInSet) Delete(x int) {
        if set.Contains(x) {
            delete(set.data, x)
            set.functions = append(set.functions, func() {
                set.Add(x)
            })
        }
    }
    
    func (set *UndoableInSet) Add(x int) {
        if !set.Contains(x) {
            set.data[x] = true
            set.functions = append(set.functions, func() {
                set.Delete(x)
            })
        }
    }
    
    func (set *UndoableInSet) Undo() error {
        if len(set.functions) == 0 {
            return errors.New("No functions to undo")
        }
        index := len(set.functions) - 1
        if function := set.functions[index]; function != nil {
            function()
            set.functions[index] = nil
        }
        set.functions = set.functions[:index]
        return nil
    }
    
    
    
    func NewInSet() InSet {
        return InSet{data:make(map[int]bool)}
    }
    
    func (set *InSet) Add(x int) {
        if set.Contains(x) {
            set.data[x] = true
            set.undo.Add(func() {
                set.Delete(x)
            })
        } else {
            set.undo.Add(nil)
        }
    }
    
    func (set *InSet) Delete(x int) {
        if set.Contains(x) {
            delete(set.data, x)
            set.undo.Add(func() {
                set.Add(x)
            })
        } else {
            set.undo.Add(nil)
        }
    }
    
    func (set *InSet) Contains(x int) bool {
        return set.data[x]
    }
    
    func (set *InSet) Undo() error {
        return set.undo.Undo()
    }
    
    func (set *InSet) String() string {
        if len(set.data) == 0 {
            return "{}"
        }
        ints := make([]int, 0, len(set.data))
        for i := range set.data {
            ints = append(ints, i)
        }
        sort.Ints(ints)
        parts := make([]string, 0, len(ints))
        for _, i := range ints {
            parts = append(parts, fmt.Sprint(i))
        }
        return "{" + strings.Join(parts, ",") + "}"
    }
    
    func main() {
        ints := NewUndoableInSet()
        for _, i := range []int{1, 2, 3, 4} {
            ints.Add(i)
            fmt.Println(ints)
        }
        fmt.Println()
        for {
            if err := ints.Undo(); err != nil {
                break
            }
            fmt.Println(ints)
        }
    }
    
    type Undo []func()
    
    func (undo *Undo) Add(function func()) {
        *undo = append(*undo, function)
    }
    
    func (undo *Undo) Undo() error {
        functions := *undo
        if len(functions) == 0 {
            return errors.New("No functions to undo")
        }
        index := len(functions) - 1
        if function := functions[index]; function != nil {
            function()
            functions[index] = nil
        }
        *undo = functions[:index]
        return nil
    }

    参考自陈皓的极客时间 https://time.geekbang.org/column/article/2748

    end

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    Inno Setup入门(六)——在程序目录下创建文件
    Inno Setup入门(五)——添加readme文件
    Inno Setup入门(四)——为程序创建桌面快捷方式
    Inno Setup入门(三)——指定压缩方式
    Inno Setup入门(二)——修改安装过程中的图片
    61 origin授控于MATLAB
    origin里用c语言编程
    flac3d自定义变量输出云图
    C语言学生管理系统源码分享
    c语言学生信息管理系统-学习结构体
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12404819.html
Copyright © 2011-2022 走看看