golang提供的List

gotaly · · 7537 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


作为现代10后语言的golang(12年正式发布)。Golang的标准库提供了高级的数据结构List。具体在包container/list。该包里主要有两个数据结构组成:“Element”、“List”。其中“Element”相当于CPP里面的"iterator",其有Prev和Next方法用于得到前一个或者下一个迭代器,迭代器的间接引用直接使用其成员Value。

1 创建一个List对象来感受一下

l聽:=聽list.New()
l.PushBack("one")
l.PushBack(2)

fmt.Println(l)

上面的代码可以得到如下的输出:

&{{0x2081a21b0聽0x2081a21e0聽<nil>聽?reflect.Value?}聽2}

这里具体的0x数据可能会变动,其实际记录的是对象的地址,但是最后的“2”不会变动,其表示当前的list对象里面有两个元素。

这里我们通过使用聽list.New()聽创建一个list对象,然后调用该对象的PushBack()方法向list对象中插入一个元素。这里我们发现神奇的一个现象:在CPP里面,list的成员的必须是同一个类型的,但是我们的Golang却允许list中插入任意类型的成员。这个很容易让我们想到了python的特性。这里我们可以通过源码了解到Element中其实存储的是一个聽interface{}聽成员,从而支持任意成员的特性:

type聽Element聽struct聽{

//聽The聽value聽stored聽with聽this聽element.
Value聽interface{}
//聽contains聽filtered聽or聽unexported聽fields
}

2.遍历list

上面的例子,仅仅用fmt.Println看到了list得简单的信息,那么若要遍历整个list怎么操作呢?来看代码:

l聽:=聽list.New()
l.PushBack("one")
l.PushBack(2)
l.PushBack("three")

for聽iter聽:=聽l.Front();iter聽!=聽nil聽;iter聽=聽iter.Next()聽{
聽聽聽聽fmt.Println("item:",iter.Value)
}

运行代码,我们可以看到结果:

item:聽one
item:聽2
item:聽three

这里,我们定义了一个迭代器变量iter,其为Element类型,通过调用list的聽Front()函数,可以得到list的第一个对象,若list为空,则得到nil。同样的通过调用调用list的Back()可以得到最后一个对象的迭代器。在for语句中,我们用list的Next()方法得到当前迭代器的下一个元素的迭代器,若没有元素了,则返回nil。因此我们用聽iter !=nil作为循环结束条件。上面说了。通过引用迭代器的Value成员,可以实现对其内存储元素的间接应用。

除了可以通过上面的函数得到单个元素外,我们还可以通过list的Len()函数获得其内元素的个数。美中不足的是Golang的List没有提供python中得通过索引引用元素的功能,也没有index或者at类似的接口

3.修改list的成员

在上面的例子中,我们已经演示了怎么向list中添加元素。PushBack()会将新元素添加到list的尾部。除此之外,还有PushFront()可以将元素插入到list得首部。InsertAfter()能将元素插入到list中指定元素的后面,InsertBefor能将元素插入到list中指定的元素的前面。

插入后如何删除元素呢?通过list的Remove()函数可以删除指定的元素。与Insert对应的MoveAfter()MoveBefore(),可以list中指定元素的后面或者前面的元素。

我们来看一个实例。用这几个接口组合成一个Queue的实例:

type聽Queue聽struct聽{
聽聽聽聽data聽*list.List
}

func聽NewQueue()聽*Queue聽{
聽聽聽聽q聽:=聽new(Queue)
聽聽聽聽q.data聽=聽list.New()
聽聽聽聽return聽q
}

func聽(q聽*Queue)Enqueue(v聽interface{})聽{
聽聽聽聽q.data.PushBack(v)
}

func聽(q聽*Queue)Dequeue()聽interface{}聽{
聽聽聽聽iter聽:=聽q.data.Front()
聽聽聽聽v聽:=聽iter.Value
聽聽聽聽q.data.Remove(iter)
聽聽聽聽return聽v
}

func聽(q聽*Queue)聽Dump(){
聽聽聽聽for聽iter:=q.data.Front();iter!=nil;iter=iter.Next()聽{
聽聽聽聽聽聽聽聽fmt.Println("item:",iter.Value)
聽聽聽聽}
}

func聽main(){
聽聽聽聽q聽:=聽NewQueue()
聽聽聽聽q.Enqueue("one")
聽聽聽聽q.Enqueue("two")
聽聽聽聽q.Dump()
聽聽聽聽v聽:=聽q.Dequeue()

聽聽聽聽fmt.Println("v:",v)
聽聽聽聽q.Dump()

}

我们可以看到结果为:

item:聽one
item:聽two
v:聽one
item:聽two

最后。如果我们想清空list。可以调用其Init()聽接口。



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:gotaly

查看原文:golang提供的List

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

7537 次点击  
加入收藏 微博
上一篇:go channel实现
下一篇:golang精华资源
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传