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
  • 相关阅读:
    没有 Lambda 演算何来匿名函数——匿名函数(匿名方法和Lambda)、委托、LINQ
    HTML 4.01 符号实体
    利用 IHttpModule 自定义 HTTP 处理模块
    数据结构单链表
    Ext.Net 1.2.0_Ext.Net.RendererFormat 常用数据格式转换呈现格式
    ASP.NET 以 Request.Querystring、Request.Form 或 Request.Params 获取客户端的数据
    Flex>连接WebService
    java.sql.SQLException: 关闭的连接
    jsp>SmartUpload相关类说明
    flex>样式和主题
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12404819.html
Copyright © 2011-2022 走看看