为什么要使用list/ Ring的Element和Ring结构体?



为什么golang中的list/ring类型使用额外的结构体Element/ring来处理单个项目而不是接口{}?我假设有一些好处,但我看不出来。

编辑:我的意思是问api,而不是关于在实现中使用元素/环。实现仍然可以使用非导出类型,但有api给出和接受接口{},那么为什么要让用户进出Element/Ring?

Edit2:作为一个例子,列表Back()函数可以像

func (l *List) Back() interface{} {
    if l.len == 0 {
        return nil
    }
    return l.root.prev.Value
}

列表内部仍然使用Element,但它将只是Element(未导出),因为它不会返回它,而只返回值

容器/列表是链表,所以List结构体可以对整个列表进行操作,并跟踪列表的开始和结束,这是有益的。

由于它是一个链表,您希望能够将项目链接在一起,并从一个项目导航到下一个或上一个项目。这需要一个结构体来保存指向下一项和上一项的指针,并允许您导航到这些项(使用next()和Prev()函数)。Element结构体用于此目的,它包含指向下一项/上一项的指针以及实际值。

结构体是这样定义的,它们也有不同的成员函数

type List struct {
    root Element // sentinel list element, only &root, root.prev, and root.next are used
    len  int     // current list length excluding (this) sentinel element
}
type Element struct {
    // Next and previous pointers in the doubly-linked list of elements.
    // To simplify the implementation, internally a list l is implemented
    // as a ring, such that &l.root is both the next element of the last
    // list element (l.Back()) and the previous element of the first list
    // element (l.Front()).
    next, prev *Element
    // The list to which this element belongs.
    list *List
    // The value stored with this element.
    Value interface{}
}

container/ring不像你暗示的那样有一个"额外的"结构体。只有Ring结构体,它将一项链接到下一项/上一项,并保存值。没有开始/结束环,所以不需要有一个结构体作为一个整体对环进行操作,也不需要跟踪开始。

type Ring struct {
    next, prev *Ring
    Value      interface{} // for use by client; untouched by this library
}

包含过滤或未导出的字段。


包列表

File list.go:

// Package list implements a doubly linked list.
// Element is an element of a linked list.
type Element struct {
    // Next and previous pointers in the doubly-linked list of elements.
    // To simplify the implementation, internally a list l is implemented
    // as a ring, such that &l.root is both the next element of the last
    // list element (l.Back()) and the previous element of the first list
    // element (l.Front()).
    next, prev *Element
    // The list to which this element belongs.
    list *List
    // The value stored with this element.
    Value interface{}
}

包环

File ring.go:

// Package ring implements operations on circular lists.
// A Ring is an element of a circular list, or ring.
// Rings do not have a beginning or end; a pointer to any ring element
// serves as reference to the entire ring. Empty rings are represented
// as nil Ring pointers. The zero value for a Ring is a one-element
// ring with a nil Value.
//
type Ring struct {
    next, prev *Ring
    Value      interface{} // for use by client; untouched by this library
}

显然,ElementRing的类型不可能是interface{},因为这没有意义。你不能在接口类型上使用方法。

Go编程语言规范

方法声明

方法是带有接收者的函数。方法声明绑定一个标识符(方法名)与方法关联,并关联该方法与接收者的基本类型。

MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
Receiver     = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
BaseTypeName = identifier .

接收方类型必须是T或*T的形式,其中T是类型名。用T表示的类型称为接收基类型;它一定不是指针或接口类型和它必须以相同的方式声明包作为方法。该方法被称为绑定到基类型方法名只在该类型的选择器中可见。

相关内容

最新更新