- 数组的声明方式是
var varName [len]T
如果len
是三个点(...)那么数组长度将根据数据初始化时的个数来决定 - 数组的中的元素都有零值,根据数组类型
T
决定,int
是0
,string
是空字符串""
- 数组的长度是常量,因此是不可变的
- 数组无法比较大小,只能比较是否相等,长度和值一样才相等
- 切片的底层就是指向数组的指针,在引用某个切片
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)
- 切片的创建方式有两种
-
通过数组创建
// 创建一个数组 var arr = [5]int{1, 2, 3, 4, 5} // 创建一个切片 var slice = arr[1:3]
-
通过内置函数
make
创建,make([]T, len, cap)
,其中len
是切片的长度,cap
是切片的容量// 创建一个切片 var slice = make([]int, 5, 10) // len=5, cap=10
len必须指定,cap可以不指定并且在指定cap的值时cap的值必须要大于等于len
-
- 切片长度是指切片中元素的个数,切片容量是指底层数组中元素的个数
- 切片的长度和容量可以通过内置函数
len
和cap
来获取 - 切片的长度和容量可以通过
append
函数来改变
如果切片的长度和容量都小于 1024,那么切片的容量会翻倍,如果大于 1024,那么切片的容量会增加 25%
- 切片的长度和容量可以通过内置函数
切片的截取时最终得到的切片会根据
slice[begin:end]
- 切片的截取写法
splice[begin:end]
半开区间,包含 begin,排除 endsplice[:end]
从下标 0 开始到下标 end-1 的元素splice[begin:]
从下标 begin 开始所有的元素splice[:]
从下标 0 开始到下标最大值位置的元素(即所有元素)
中上界下界的值进行界定,而写法有多种要么没定义上界要么没定义下界,总的来说下界定义了 就是最后一个元素取下标为下界值减一,反之则是都要(加深自我理解)
- 切片的遍历方式有两种
- 通过
for
循环加上range
关键字 - 通过
for
循环加上len
函数和下标
- 通过
- 切片的拷贝有两种方式
- 通过
copy
函数- 内置函数
copy(target, source []Type)
可以将切片source
的值覆盖到切片target
里面,返回的值是拷贝元素的个数,并且由两者之间最小长度决定
- 内置函数
- 通过
append
函数- 内置函数
append(slice []Type, elems ...Type)
将元素附加到slice
后面得到一个新的切片(这个elems
可以是一个同类型的切片)
- 内置函数
- 通过
元素对的无序集合
map
是引用类型,当将map
传递给函数时,函数内部对map
的修改会影响到原来的map
map
的声明方式var mapName map[T]T
,其中第一个T
是key
的类型,第二个T
是value
的类型key
的类型必须满足可比较的要求,即==
和!=
操作符可用于该类型,value
的类型没有限制
在
go
中因为线程安全的问题将map
分为了无锁的map
和自带锁的sync.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
不存在也不会有问题(排除极端情况)
// 声明方式
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
})
此种类型操作都是基于自带函数