首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在golang list/ring中使用Element和Ring结构?

为什么在golang list/ring中使用Element和Ring结构?
EN

Stack Overflow用户
提问于 2014-06-18 04:32:11
回答 2查看 1.9K关注 0票数 4

为什么golang中的list/ring类型对单个项使用额外的structs元素/Ring,而不是interface{}?我假设有一些好处,但我看不到它。

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

Edit2:举个例子,list Back()函数可以是这样的

代码语言:javascript
复制
func (l *List) Back() interface{} {
    if l.len == 0 {
        return nil
    }
    return l.root.prev.Value
}

其中列表仍然在内部使用元素,但它将只是元素(未导出),因为它不会返回它,而只是返回值。

EN

回答 2

Stack Overflow用户

发布于 2014-06-18 05:11:49

container/list是链表,所以让List结构可以作为一个整体对list进行操作并跟踪list的开始和结束将是有益的。

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

下面是如何定义结构,它们也有不同的成员函数

代码语言:javascript
复制
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{}
}

容器/环没有您所暗示的“额外”结构。只有Ring结构,它将一项链接到下一项/上一项,并保存值。Ring没有start/end,所以没有必要有一个结构来作为一个整体对一个环进行操作,或者跟踪开始。

代码语言:javascript
复制
type Ring struct {
    next, prev *Ring
    Value      interface{} // for use by client; untouched by this library
}
票数 4
EN

Stack Overflow用户

发布于 2014-06-18 05:09:02

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

Package list

文件list.go

代码语言:javascript
复制
// 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{}
}

Package ring

文件ring.go

代码语言:javascript
复制
// 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{},因为这没有任何意义。接口类型上不能有方法。

The Go Programming Language Specification

Method declarations

方法是具有接收器的函数。方法声明将标识符、方法名绑定到方法,并将该方法与接收方的基类型相关联。

MethodDecl = "func“接收方签名( MethodName | Signature )。Receiver = "(“identifier BaseTypeName ")”。BaseTypeName =标识符。

接收器类型必须为T或*T形式,其中T是类型名称。由T表示的类型称为接收器基类型;它不能是指针或接口类型,并且必须在与方法相同的包中声明。该方法被称为绑定到基类型,并且方法名称仅在该类型的选择器中可见。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24272789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档