dushaoshuai / dushaoshuai.github.io

https://www.shuai.host
0 stars 0 forks source link

Iterator #79

Open dushaoshuai opened 1 year ago

dushaoshuai commented 1 year ago

Iterator 模式允许在不暴露复杂数据结构内部细节的情况下,以不同方式(算法)遍历其中的元素。迭代方法抽象成一个 Iterator 接口,不同的迭代算法对应一个实现了 Iterator 接口的具体类型。

一个简单实现

iterator.go

type Iterator interface {
    HasNext() bool
    GetNext() *Elem
}

type Elem struct {
    Name string
}

type Collection struct {
    data []*Elem
}

func NewCollection(elems ...*Elem) *Collection {
    c := &Collection{}
    for _, e := range elems {
        c.data = append(c.data, e)
    }
    return c
}

// forward traversal
type f struct {
    *Collection
    index int
}

func (es *Collection) ForwardIterator() Iterator {
    return &f{Collection: es, index: 0}
}

func (f *f) HasNext() bool {
    return f.index < len(f.data)
}

func (f *f) GetNext() *Elem {
    if !f.HasNext() {
        return nil
    }
    e := f.data[f.index]
    f.index++
    return e
}

// reverse traversal
type r struct {
    *Collection
    index int
}

func (es *Collection) ReverseIterator() Iterator {
    return &r{
        Collection: es,
        index:      len(es.data) - 1,
    }
}

func (r *r) HasNext() bool {
    return r.index >= 0
}

func (r *r) GetNext() *Elem {
    if !r.HasNext() {
        return nil
    }
    e := r.data[r.index]
    r.index--
    return e
}

iterator_test.go

func Example_iterator() {
        // use Visitor along with Iterato to traverse a complex data structure
    visit := func(e *iterator.Elem) {
        fmt.Println(e.Name)
    }

    c := iterator.NewCollection(
        &iterator.Elem{Name: "Go"},
        &iterator.Elem{Name: "C"},
        &iterator.Elem{Name: "Java"},
    )

    f := c.ForwardIterator()
    for f.HasNext() {
        visit(f.GetNext())
    }

    r := c.ReverseIterator()
    for r.HasNext() {
        visit(r.GetNext())
    }

    // Output:
    // Go
    // C
    // Java
    // Java
    // C
    // Go
}