Go语言学习笔记2-容器

数组

和C#中的数组相同,也是一段固定长度的内存区域


切片

  1. 切片默认指向一段连续的内存区域,可以是数组,也可以是切片本身
    切片对象 [开始位置 : 结束位置]
    • 取出元素遵从左闭右开
    • 开始位置缺省时,表示从连续区域开头到结束位置
    • 结束位置缺省时,表示从开始位置到整个连续区域末尾
    • 两者都缺省时,表示与切片本身等效
    • 两者为0时,表示空切片,一般用于复位
1
2
var a = [3]int{1, 2, 3}
var slice = a[1:2]
  1. 动态的创建一个切片可以使用 make() 内建函数
    make([]T, 元素数量, 预分配元素数量)
    预分配数量不影响size,只是提前分配空间,降低多从分配空间造成的性能问题
1
2
a := make([]int, 2)
b := make([]int, 2, 10)
  1. 使用内建函数 append() 可以为切片动态添加元素
    当切片的内存空间不能容纳足够的元素时会进行扩容,容量的扩展规律按容量的2倍数扩充
1
2
3
4
5
6
7
8
9
10
11
var numbers []int
for i := 0; i < 10; i++ {
numbers = append(numbers, i)
}

//添加多个元素
numbers = append(numbers, 1, 2, 3)

//添加切片
slice := []int{4, 5, 6}
numbers = append(numbers, slice...)
  1. 使用内建函数 copy() 可以将一个切片的数据复制到另外一个切片空间中
    copy(目标切片, 数据来源切片)
    目标切片必须分配过空间切足够承载复制的元素个数,来源和目标的类型一致,copy的返回值表示实际复制的元素个数
1
2
3
4
5
6
7
8
const elementCount = 10
srcData := make([]int, elementCount)
for i := 0; i < elementCount; i++{
srcData[i] = i
}

copyData := make(int[], elementCount)
copy(copyData, srcData)
  1. 切片没有删除元素的内建函数,可以使用切片本身的特性来删除元素
    以被删除元素为分界点,将前后两个部分的内存重新连接起来
    此过程会将删除点前后的元素移动到新的位置,随着元素的增加,这个过程会变得极为耗时,对于频繁删除元素的情况应使用双链表等容器
1
2
3
seq := []string{"a", "b", "c", "d", "e"}
index := 2
seq = append(seq[:index], seq[index+1:]...)

映射

  1. map的定义
    map[键的类型] 值的类型
1
2
3
4
5
6
7
8
9
10
scene := make(map[string] int)
scene["route"] = 66

//在申明时填充内容
m := map[string]string{
"W": "forward",
"A": "left",
"S": "backward",
"D": "right",
}
  1. 使用 for range 遍历map
    map是无序的,遍历输出的顺序和填充顺序无关
1
2
3
4
5
6
7
8
9
scene := make(map[string] int)

scene["route"] = 66
scene["brazil"] = 4
scene["chian"] = 960

for k, v := range scene{
fmt.Println(k, v)
}
  1. 使用 delete() 删除map的键值对
    delete(map, 键)
  2. map并没有内建的清空函数,在需要清空时重新make一个新的map即可
  3. 并发环境中使用sync.Map来替代map
  • 无需初始化,声明即可用
  • sync.Map使用 Store(存储)、Load(获取)、Delete(删除)完成取值和设置等操作
  • 使用Range配合回调函数进行遍历操作,回调函数返回true继续遍历,返回false终止遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var scene sync.Map

scene.Store("greece", 97)
scene.Store("london", 100)
scene.Store("egypt", 200)
fmt.Println(scene.Load("london"))

scene.Delete("london")

//遍历键值对
//sync.Map没有提供获取map数量的方法,使用range遍历计算数量
var count int
scene.Range(func(k, v interface{}) bool{
count++
fmt.Println("interface:", k, v)
return true
})
fmt.Println("元素数量:", count)

列表

  1. 列表是一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系
  2. 列表的初始化
    • 变量名 := list.New()
    • var 变量名 list.List
  3. 使用PushFrontPushBack向列表插入元素
1
2
3
4
l := list.New()

l.PushBack("first")
l.pushFront(1)
方法 功能
InsertAfter(v interface{}, mark *Element) *Element 在mark点之后插入元素,mark点由其他插入函数提供
IntertBefore(v interface{}, mark *Element) *Element 在mark点之前插入元素,mark点由其他插入函数提供
PushBackList(other *List) 添加other列表元素到尾部
PushFrontList(other *List) 添加other列表元素到头部
  1. 插入元素时会返回一个 *list.Element 结构,在后续删除插入的元素时只能通过 *list.Element 配合Rmove() 进行删除
1
2
3
4
5
6
7
8
9
10
11
12
l := list.New()
l.PushBack("canon") //元素:canon
l.pushFront(67) //元素:67, canon

element := l.PushBack("fist") //元素:67, canon, fist
//在fist之后添加high
l.InsertAfter("high", element) //元素:67, canon, fist, high
//在fist之前添加noon
l.InsertBefore("noon", element) //元素:67, canon, noon, fist, high

//删除fist
l.Remove(element) //元素:67, canon, noon, high
  1. 配合 Front() 获取头元素来进行遍历
1
2
3
4
5
6
7
l := list.New()
l.PushBack("canon")
l.PushFront(67)

for i := l.Fornt(); i != nil; i = i.Next() {
fmt.Println(i.Value)
}
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021 Azella
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信