一、一维数组
//声明一个包含5个元素的整型数组
var array [5]int
//具体数值填充数组
array := [5]int{1, 2, 3, 4, 5}
//容量由初始化值的数量决定
array := [...]int{1, 2, 3, 4, 5)
//只初始化索引为1和2的元素
array := [5]int{1: 10, 2: 20}
//修改索引为2的元素的值
array[2] = 35
//指针数组
//声明包含5个元素的指向整数的数组
//用整形指针初始化索引为0和1的数组
array := [5]*int{0: new(int), 1: new(int)}
//为索引为0和1的元素赋值
*array[0] = 10
*array[1] = 20
①数组一旦声明,其数据类型和数据长度就都不能改变
②数组长度和元素类型都相同的数组,可以直接用=相互赋值
③复制指针数组,只会复制指针的值,而不会复制指针所指向的值
二、多维数组
//声明一个二维整型数组
var array [4][2]int
//使用数组字面量来声明并初始化
array1 := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
//声明并初始化外层数组索引为1和3的元素
array2 := [4][2]int{1:{20, 21}, 3:{40, 41}}
//声明并初始化外层数组和内层数组的单个元素
array3 := [4][2]int{1: {0:20}, 3:{1: 41}}
//单个元素直接赋值
array1[0][0] = 10
//同种数组直接赋值
array1 = array2
三、切片
切片是一种数据结构,这种数据结构便于使用和管理数据集合。
切片围绕动态数组展开,可以按需自动增长和缩小,其动态增长是通过内置函数append来实现的。这个函数可以快速且高效的增长切片。
创建和初始化
//创建一个长度为3,容量为5个元素,容量即切片允许增长到的最大长度
slice := make([]int, 3, 5)
//创建一个长度和容量都是5个元素
slice := []int{10, 20, 30, 40, 50}
//改变值
slice[1] = 25
//创建一个新切片,其长度为2,容量为4
newSlice := slice[1:3]
//使用原来的容器来分配一个新元素,将新元素赋值为60
newSlice = append(newSlice, 60)
//使用append将一个切片追加到另一个切片,可变参数
append(slice, newSlice, ...)
//使用range遍历切片元素
for index, value := range slice {
fmt.Printf("Index:%d Value: %d\n", index, value)
}
//使用传统的for循环对切片进行迭代
for index := 0; index < len(slice); index++{
fmt.Printf("Index: %d Value: %d\n", index, slice[index])
}
//声明一个多维切片
slice := [][]int{{10}, {100, 200}}
//为第一个切片追加值为20的元素
slice[0] = append(slice[0], 20)
//在函数间传递切片
func foo(slice []int)[]int {
...
return slice
}
①简而言之,切片之所以被称为切片,是因为创建一个新的切片就是把底层数组切出一部分。
②对于底层数组容量是k的切片slice[i,j],其长度是j-i,容量是k-i.
③使用切片创建切片时,其公用一个底层数组,改变一个切片,另一个切片随之改变
④append会智能地处理底层数组的容量增长。在切片的容量小于1000个元素时,总是会成倍的增长容量,一旦元素超过1000,容量的增长因子会设为1.25。需注意的是,append智能增长时会使用一个新的底层数组。
⑤创建新切片时还可以使用第三个索引选项,用来控制新切片的容量
对于slice[i,j,k],其长度为j-i,其容量为k-i。
⑥使用range遍历切片元素时会返回两个值,第一个值时当前迭代到的索引位置,第二个时该位置对应元素值的一份副本
⑦对于切片,有两个内置的函数len和cap,分别返回长度及容量.
⑧在64位架构的机器上,一个切片需要24字节的内存;指针字段需要8字节,长度和容量字段分别需要8字节。由于切片关联的数据包含在底层数组里,不属于切片本身,所以将切片复制到任意函数时,对底层数组大小都不会有影响。
四、映射
映射是一种数据结构,用于存储一系列无序的键值对。其实现使用了散列表。
//创建一个映射,键的类型是string,值的类型是int
dict := make(map[string]int)
//创建一个映射,键的类型是string,值的类型是string,并初始化
dict := map[string]string{"Red": "#da1337", "Orange": "#e95a22"}
//从映射中取值并判断其是否存在
value, exists := dict["Blue"]
if exists {
fmt.Println(value)
}
//遍历映射
for key, value := range dict {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
//删除
delete(dict, "Red")
注意:将切片或者映射传递给函数成本很小,并且不会复制底层的数据结构。