💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # list链表 `List`和`Element`。前者实现了一个双向链表(以下简称链表),而后者则代表了链表中元素的结构。 `List`和`Element`都是结构体类型。结构体类型有一个特点,那就是它们的零值都会是拥有其特定结构,但没有任何定制化内容的值,相当于一个空壳 ## 主要方法 * `MoveBefore`:给定的元素移动到另一个元素的前面 * `MoveAfter`:给定的元素移动到另一个元素的后面 * `MoveToFront`:把给定的元素移动到链表的最前端 * `MoveToBack`:把给定的元素移动到链表的最后端 * `Front`:获取链表中最前端 * `Back`:获取链表中最后端 * `InsertBefore`:指定的元素之前插入新元素 * `InsertAfter`:指定的元素之后插入新元素 * `PushFront`:用于在链表的最前端插入新元素。 * `PushBack`:用于在链表的最前端插入新元素。 **注意点** 在`List`包含的方法中,用于插入新元素的那些方法都只接受`interface{}`类型的值。这些方法在内部会使用`Element`值包装接收到的新元素。 这样做正是为了避免直接使用我们自己生成的元素,主要原因是避免链表的内部关联遭到外界破坏,这对于链表本身以及我们这些使用者来说,都是有益的 **为什么链表可以做到开箱即用?** 延迟初始化,你可以理解为把初始化操作延后,仅在实际需要的时候才进行。延迟初始化的优点在于“延后”,它可以分散初始化操作带来的计算量和存储空间消耗。 `List`利用了自身,以及`Element`在结构上的特点,巧妙地平衡了延迟初始化的优缺点,使得链表可以开箱即用,并且在性能上可以达到最优 ## 结构 ~~~ type Element struct { // 元素保管的值 Value interface{} // 内含隐藏或非导出字段 } ~~~ list包实现了双向链表。要遍历一个链表: ~~~ for e := l.Front(); e != nil; e = e.Next() { // do something with e.Value } ~~~ Example ~~~ // Create a new list and put some numbers in it. l := list.New() e4 := l.PushBack(4) e1 := l.PushFront(1) l.InsertBefore(3, e4) l.InsertAfter(2, e1) // Iterate through list and print its contents. for e := l.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } ~~~ Output: ~~~ 1 2 3 4 ~~~ ## 使用 ~~~ package main; import ( "container/list" "fmt" ) func printList(l *list.List) { for e := l.Front(); e != nil; e = e.Next() { fmt.Print(e.Value, " "); } fmt.Println(); } func main() { //创建一个链表 l := list.New(); //链表最后插入元素 a1 := l.PushBack(1); b2 := l.PushBack(2); //链表头部插入元素 l.PushFront(3); l.PushFront(4); printList(l); //取第一个元素 f := l.Front(); fmt.Println(f.Value); //取最后一个元素 b := l.Back(); fmt.Println(b.Value); //获取链表长度 fmt.Println(l.Len()); //在某元素之后插入 l.InsertAfter(66, a1); //在某元素之前插入 l.InsertBefore(88, a1); printList(l); l2 := list.New(); l2.PushBack(11); l2.PushBack(22); //链表最后插入新链表 l.PushBackList(l2); printList(l); //链表头部插入新链表 l.PushFrontList(l2); printList(l); //移动元素到最后 l.MoveToBack(a1); printList(l); //移动元素到头部 l.MoveToFront(a1); printList(l); //移动元素在某元素之后 l.MoveAfter(b2, a1); printList(l); //移动元素在某元素之前 l.MoveBefore(b2, a1); printList(l); //删除某元素 l.Remove(a1); printList(l); } ~~~