这是我参与「第五届青训营」伴学笔记创作活动的第4天。
在之前的笔记中,我总结了Go语言的函数、循环、数组、条件分支等的基本用法。这一篇笔记接续前文,整理Go语言中的切片、集合等概念。
切片 (Slice)
Go语言的数组(array)不能动态扩容,也不能使用变量指定数组的长度,这为开发带来了不方便。使用Go语言的切片(slice)功能可以避开这些不便。Go语言的切片和Java中的ArrayList、C++中的vector有些类似,都是一种容量可变的数组结构。
切片的类型定义与数组基本一致,为var identifier []type,即未指定大小的数组。要创建一个切片,可以借助于make函数,例如:
slice1 := make([]int, 0, 5)
make函数各个参数的意义分别是类型、长度和初始容量,即make([]type, length, capacity),其中初始容量capacity为可选参数,这意味着在数据数量可以估计时可以通过事先指定capacity来减少切片扩容的开销。make函数的第一个参数类型为[]type,即数组类型,这个参数指定了切片的数据类型;第二个参数length为切片的初始长度,上面的例子中第二个参数为0意味着创建一个空的不含任何元素的切片。
除了使用make函数创建切片,还可以直接使用[] type的形式创建切片,例如:
s := [] int {1, 2, 3}
这条语句创建了一个包含三个元素(1,2,3)的整数类型的切片,该切片的长度和容量均为3。注意,这条语句与创建数组的语句不同,要创建数组,应当使用:
s := [...] int {1, 2, 3}
这会创建一个长度为3的数组,而非切片,无法进行容量动态增加和元素追加。
切片可以像数组一样使用下标访问其中的元素,也可以使用类似slice[:]的方式访问其中的多个元素。例如:
s := [] int {1, 2, 3}
a := s[idx1:idx2] // 取出从下标idx1到idx2的元素,创建一个新切片
b := s[idx1:] // 取出从下标idx1到最后的全部元素,创建一个新切片
d := s[:idx2] //取出从第一个元素到下标idx2的元素,创建一个新切片
要获得一个切片的长度和容量,可以使用len、cap这两个函数,例如len(s)将返回切片s的长度,而cap(s)将返回切片s的容量。
如果要向切片追加元素,可以使用append函数,例如:
s := [] int {1, 2, 3}
s = append(s, 4) // s现在为{1, 2, 3, 4}
s = append(s, 5, 6, 7) // s 现在为{1, 2, 3, 4, 5, 6, 7}
此外,还可以使用copy函数拷贝一个切片的内容到另一个切片,例如:
var numbers []int
numbers.append(numbers, 1, 2, 3, 4) // numbers : {1, 2, 3, 4}
var numbers1 := make([]int, len(numbers))
copy(number1, numbers) // 将numbers的内容拷贝到numbers1
集合 (Map)
Go语言的Map与其他很多语言一样,指的是键值对的集合。Map中的每一个元素包括一个key和一个value,一个Map中的各个key需要互不相同。Map的创建有两种常见的方式,一种是借助于make函数,一种是直接使用map关键字,例如:
m := make(map[string]int) // key的类型为string,value的类型为int
var m1 map[string]int
m2 := map[string]int{"one": 1, "two": 2}
直接使用key的值作为下标即可访问对应的元素,如果要添加元素,也可以直接通过赋值的方式添加,例如:
m["one"] = 1 // 添加元素
fmt.Println(m["one"]) //访问元素
如果要删除一个键值对,需要借助于delete函数,如下所示:
delete(m, "one") // 删除m["one"]
此外,map是无序的,因此其在迭代时的顺序是未定义的。