如何使用通用结构

时间:2017-01-29 17:28:51

标签: go

我有订单列表的结构。我想订购map并找到它。但我不想为所有类型创造这个,我有。也许我需要另一个代码?或者我如何将其重写为通用,我可以将其用于所有类型,PrevNext

type Post struct { //for example
    P string
    O int
    Prev, Next *Post
}
type Act struct {
    I int
    Prev, Next *Act
}    

type Map struct {
    Act         map[int]*Act
    First, Last *Act
}

func (m *Map) New(a *Act) int {
    Ida++
    f := Ida
    a.Id = Ida
    m.Act[Ida] = a
    if m.First == nil {
        m.First = a
    } else {
        m.Last.Next = a
        a.Prev = m.Last
    }
    m.Last = a
    return f
}

func (m *Map) Del(s int) {
    if _, ok := m.Act[s]; ok {
        if m.Last == m.First {
            m.Last = nil
            m.First = nil
            delete(m.Act, s)
            return
        }
        if m.Last == m.Act[s] {
            m.Last = m.Act[s].Prev
            m.Act[s].Prev.Next = nil
            delete(m.Act, s)
            return
        }
        if m.First == m.Act[s] {
            m.First = m.Act[s].Next
            m.Act[s].Next.Prev = nil
            delete(m.Act, s)
            return
        }
        m.Act[s].Prev.Next = m.Act[s].Next
        m.Act[s].Next.Prev = m.Act[s].Prev
        delete(m.Act, s)
        return
    }
}

2 个答案:

答案 0 :(得分:2)

您可以定义适用于实现Prev()Next()方法的所有类型的函数。比如像这样的东西

type List interface{
    Next() List
    Prev() List
    First() List
    Last() List
    Value() interface{}
    SetNext(List)
    SetPrev(List)
}
func Del(l List, elem_to_delete interface{}){
    for e:=l.First(); e != l.Last(); e = l.Next()
        if l.Value() == elem_to_delete{
            l.Prev().SetNext(l.Next())
            l.Next().SetPrev(l.Prev())
            break
        }
    }
}
//and implement those methods for your types
type Post struct { //for example
    P string
    O int
    Prev, Next *Post
}
func (p Post) Next() List{
    return p.Next
}
...
//and then you can call Del() with any of this types
Del(post, 5)

此外,您还可以使用stdlib中定义的列表数据结构。

答案 1 :(得分:1)

如果要将NextPrev操作定义为方法:

type Act struct {
    I int
    Prev, Next *Act
}

func (a *Act) GetNext(){
    return a.Next
}    

你可以有一个界面:

type PrevNext interface {
    GetNext() *Act
    GetPrev() *Act
    // ... and all other required actions
}

因此,您可以将Del()定义为不作为方法,而是定义为PrevNext类型的对象的泛型函数,并将所有必需的操作定义为方法。

func Del(m *PrevNext, s int) {
    if _, ok := m.Act[s]; ok {
        if m.GetLast() == m.GetFirst() {
            m.SetLast(nil)
            m.SetFirst(nil)
            delete(m.Act, s)
            return
        } 
    // ....
    }
}