list是列表,一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系。list有多种实现方法,如单向链表、双向链表等。
Go语言中的list的实现原理是双向链表,list能高效地进行任意位置的元素插入和删除操作。
Golang的标准库提供了高级的数据结构List,具体在包container/list。
container/list包里主要有两个数据结构类型:“Element”、“List”;
Element类型代表双向链表中的一个元素,相当于C++里面的“iterator”
List代表一个双向链表。List零值为一个空的、可用的链表。
Element有Prev和Next方法用于得到前一个或者下一个element,element可以直接调用value属性;

声明list

格式:变量名:= list.New()
var 变量名 list.List
list与切片、Map不一样,没有具体元素类型的限制。
在java、c++等里面,list的成员必须是同一个数据类型,但是Go语言中却允许list里插入任意类型成员。
建议使用New()实现list。

list的声明及添加数据
为了等下的代码能更直观的运行,先写两个print的函数

  1. func printList(i string, l list.List) {
  2. fmt.Println(i)
  3. fmt.Printf("类型:%T, 值:%v, 长度:%d \n", l, l, l.Len())
  4. }
  5. func printIterateList(l list.List){
  6. for e:=l.Front();e!=nil; e= e.Next(){
  7. fmt.Printf("%T ,%v \t", e.Value, e.Value)
  8. }
  9. }

用第一种方式声明及添加数据

  1. func testListNew() {
  2. var list1 list.List
  3. printList("测试声明list", list1)
  4. //测试声明list
  5. // 类型:list.List, 值:{{<nil> <nil> <nil> <nil>} 0}, 长度:0
  6. //添加数据
  7. list1.PushFront(true)
  8. list1.PushFront("aaaa")
  9. list1.PushFront(1.23456)
  10. list1.PushFront(123)
  11. //尾部添加数据
  12. list1.PushBack("一二三")
  13. printList("添加数据以后list", list1)
  14. //添加数据以后list
  15. // 类型:list.List, 值:{{0xc000062360 0xc000062390 <nil> <nil>} 5}, 长度:5
  16. printIterateList(list1)
  17. //int ,123 float64 ,1.23456 string ,aaaa bool ,true string ,一二三
  18. }

第二种方式声明及其他相关函数

  1. func testList1(){
  2. list1 := list.New()
  3. //用list.New()声明的list,返回的是一个指针,所以必须加上一个*号
  4. printList("",*list1)
  5. list1.PushBack("bbbbb")
  6. list1.PushFront(1)
  7. element1 := list1.PushBack("ccccc")
  8. //在element1后面插入数据
  9. list1.InsertAfter("aaaaa",element1)
  10. //在element1前面插入数据
  11. list1.InsertBefore(50,element1)
  12. printIterateList(*list1)
  13. fmt.Println()
  14. //移除element1
  15. list1.Remove(element1)
  16. printIterateList(*list1)
  17. list2 := list.New()
  18. list2.PushFront("1234")
  19. list2.PushBack("5678")
  20. fmt.Println()
  21. //在list1前面添加list2列表
  22. list1.PushFrontList(list2)
  23. printIterateList(*list1)
  24. list3 := list.New()
  25. list3.PushFront("abcd")
  26. list3.PushBack("efgh")
  27. fmt.Println()
  28. //在lisi1后面添加list3、
  29. list1.PushBackList(list3)
  30. printIterateList(*list1)
  31. }

list的遍历:

先建一个变量

  1. var list2 list.List

然后开始遍历该list

  1. //遍历list,顺序遍历
  2. func iterateList1() {
  3. for e := list2.Front(); e != nil; e = e.Next() {
  4. fmt.Println(e.Value)
  5. }
  6. }
  7. //遍历list,逆序遍历
  8. func iterateList2() {
  9. for e := list2.Back(); e != nil; e = e.Prev() {
  10. fmt.Println(e.Value)
  11. }
  12. }


将列表遍历到数组中

  1. func (v *MapGoroutine) readBcdnUDPPort() []string {
  2. v.RLock()
  3. arrayStr := make([]string, v.bcdnUDPPort.Len())
  4. i := -1
  5. for e := v.bcdnUDPPort.Front(); e != nil; e = e.Next() {
  6. i++
  7. arrayStr[i] = e.Value.(string)
  8. }
  9. v.RUnlock()
  10. return arrayStr
  11. }

list是值类型:

用一个函数来证明list是值类型。

  1. func testList2(l list.List){
  2. l.PushFront("一")
  3. l.PushBack("三")
  4. printIterateList(l)
  5. fmt.Println(l.Len())
  6. }
  7. //说明list是值类型
  8. func main() {
  9. printIterateList(list2)
  10. fmt.Println()
  11. testList2(list2)
  12. list2.PushFront("二")
  13. printIterateList(list2)
  14. fmt.Println()
  15. testList2(list2)
  16. }

https://blog.csdn.net/ynzcxx/article/details/96355176