Skip to content

Latest commit

 

History

History
111 lines (90 loc) · 4.91 KB

README.md

File metadata and controls

111 lines (90 loc) · 4.91 KB

数组、切片和 map

数组

  • 数组的声明方式是 var varName [len]T 如果 len 是三个点(...)那么数组长度将根据数据初始化时的个数来决定
  • 数组的中的元素都有零值,根据数组类型 T 决定,int0string 是空字符串""
  • 数组的长度是常量,因此是不可变的
  • 数组无法比较大小,只能比较是否相等,长度和值一样才相等

切片

  • 切片的底层就是指向数组的指针,在引用某个切片 A 得到另一个切片 B 时(切片截取),改变切片 B 的元素内容,切片 A 的内容也会随之改变(这本质上就是指针的特征)
  • 切片的声明方式是 var varName []T,其中 T 是切片中元素的类型

切片必须要初始化才能使用

// 由于数组是定长的(数组的长度是其类型的一部分,因此数组不能改变大小)
// 因此在Go中更多使用的是切片,(切片是长度可以变化的数组)切片和数组又息息相关
var arrSlice []string
if arrSlice == nil {
fmt.Println("切片arrSlice是空的")
}
// arrSlice[0] = "hello" // 这一行编译通过,但是运行报错,切片只是声明了但没有初始化
// 本质上切片的底层实现是一个指向数组的指针,在没有存入一个具体的数组之前,就是 nil
// arrSlice = []string{""}  直接是以这种简单方式就可以使用
// 或者通过内置函数 make 进行初始化 make([]T, len, cap)
  • 切片的创建方式有两种
    1. 通过数组创建

      // 创建一个数组
      var arr = [5]int{1, 2, 3, 4, 5}
      // 创建一个切片
      var slice = arr[1:3]
    2. 通过内置函数 make 创建,make([]T, len, cap),其中 len 是切片的长度,cap 是切片的容量

      // 创建一个切片
      var slice = make([]int, 5, 10) // len=5, cap=10

      len必须指定,cap可以不指定并且在指定cap的值时cap的值必须要大于等于len

  • 切片长度是指切片中元素的个数,切片容量是指底层数组中元素的个数
    • 切片的长度和容量可以通过内置函数 lencap 来获取
    • 切片的长度和容量可以通过 append 函数来改变

    如果切片的长度和容量都小于 1024,那么切片的容量会翻倍,如果大于 1024,那么切片的容量会增加 25%

切片的截取时最终得到的切片会根据 slice[begin:end]

  • 切片的截取写法
    • splice[begin:end] 半开区间,包含 begin,排除 end
    • splice[:end] 从下标 0 开始到下标 end-1 的元素
    • splice[begin:] 从下标 begin 开始所有的元素
    • splice[:] 从下标 0 开始到下标最大值位置的元素(即所有元素)

中上界下界的值进行界定,而写法有多种要么没定义上界要么没定义下界,总的来说下界定义了 就是最后一个元素取下标为下界值减一,反之则是都要(加深自我理解)

  • 切片的遍历方式有两种
    1. 通过 for 循环加上 range 关键字
    2. 通过 for 循环加上 len 函数和下标
  • 切片的拷贝有两种方式
    1. 通过 copy 函数
      • 内置函数 copy(target, source []Type) 可以将切片 source 的值覆盖到切片 target 里面,返回的值是拷贝元素的个数,并且由两者之间最小长度决定
    2. 通过 append 函数
      • 内置函数 append(slice []Type, elems ...Type) 将元素附加到 slice 后面得到一个新的切片(这个 elems 可以是一个同类型的切片)

map

元素对的无序集合

  • map 是引用类型,当将 map 传递给函数时,函数内部对 map 的修改会影响到原来的 map
  • map 的声明方式 var mapName map[T]T,其中第一个 Tkey 的类型,第二个 Tvalue 的类型
  • key 的类型必须满足可比较的要求,即 ==!= 操作符可用于该类型,value 的类型没有限制

go 中因为线程安全的问题将 map 分为了无锁的 map 和自带锁的 sync.Map

无锁 map

  • 声明方式 var mapName map[T]T
  • 初始化使用内置函数 make(map[T]T)
  • map 的取值 mapName["key"],该表达式会返回两个元素,一个是值,一个是布尔类型的判断 key 是否存在于该 map
  • map 的遍历可以使用 for 循环加上 range 关键字
  • map 删除元素可以使用内置函数 delete(m map[Type]Type1, key Type),并且如果 key 不存在也不会有问题(排除极端情况)

有锁 sync.Map

// 声明方式
var syncMap sync.Map
// 初始化方式
syncMap = sync.Map{}
// 添加元素
syncMap.Store("key", "value")
// 获取元素
syncMap.Load("key")
// 删除元素
syncMap.Delete("key")
// 遍历元素
syncMap.Range(func (key, value interface{}) bool {
fmt.Println(key, value)
return true
})

此种类型操作都是基于自带函数