List底层数据结构
底层使用双向链表实现。头尾相接形成环。源码位于src\container\list\list.go
type List struct {
root Element
len int
}
func (l *List) Init() *List {
l.root.next = &l.root
l.root.prev = &l.root
l.len = 0
return l
}
从源码中可以看到List包含了长度len和根节点root,root是Element类型,接着看一下Element的源码:
type Element struct {
next, prev *Element
list *List
Value any
}
Element包含了指针next、pre,对象list,具体的值Value。个别场景,我们需要知道Element所在的链表的时候,可以利用list属性。list这个属性在插入的时候被赋值。如下:
func (l *List) insert(e, at *Element) *Element {
e.prev = at
e.next = at.next
e.prev.next = e
e.next.prev = e
e.list = l
l.len++
return e
}
懒加载
List也支持懒加载,可以直接通过new创建List对象,push的时候才创建List的内部细节,如下:
func (l *List) lazyInit() {
if l.root.next == nil {
l.Init()
}
}
func (l *List) PushFront(v any) *Element {
l.lazyInit()
return l.insertValue(v, &l.root)
}
官方接口
官方提供了很多接口对List进行操作:
Remove(*Element)Val: 将指定的Element从List中剔除(Element在List里)Back()*Element:返回最后一个元素Front()*Element:返回第一个元素lazyInit():懒加载,如果List没有初始化,则调用初始化函数Init()insert(e,at *Element):将元素e添加到at元素的后面。后续的push类型的函数都基于insertinsertValue(val any,at*Element):将值val包装成Element并插入到at的后面move(e,at *Element):将e挪到at的后面PushFront(v any)*Element: 将v push到最前面PushBack(v any)*Element: 将v push到最后面InsertBefor(v any,mark *Element):将v包装成Element,插入到mark之前,前提mart是当前List的元素InsertAfter(v any,mark *Element):将v包装成Element,插入到mark之后,前提mart是当前List的元素MoveToFront(e *Element):将e挪到最前面。MoveToBack(e *Element):将e挪到最后面。MoveBefore(e,at *Element):将e挪到at之前。MoveAfter(e,at *Element):将e挪到at之后。PushBackList(other *List):遍历other,将其元素全部顺序追加到当前List的末尾。PushFrontList(other *List):遍历other,将其元素全部顺序追加到当前List的前面。(PushBackList,PushFrontList中,从other中获取插入当前List的Element是一个新对象)