数组和切片
1.数组
(1)数组的定义
var arr1 [3]int = [3]int{1,2,3}
var arr2 = [3]int{1,2,3}
var arr3 = [...]int{1,2,3}
var arr4 = [...]int{0: 1, 1: 2, 2: 3}
(2)数组的遍历
func main() {
arr := [...]int{1,2,3}
//法一
for i:=0;i<len(arr);i++ {
fmt.Println(arr[i])
}
//法二
for i,v := range arr {
//i:索引 v,arr[i]:值
fmt.Println(i,v,arr[i])
}
}
2.切片
一个动态变化的数组
(1)切片的定义
//法一
arr := [...]int{1, 2, 3}
slice1 := arr[0:3]//左含右不含
fmt.Println(slice1)
//法二
var slice2 []int = make([]int,5,6)//5:长度 6:容量
fmt.Println(slice2)
//法三,同定义数组,但不用声明长度
var slice3 []int = []int{1,2,3}
fmt.Println(slice3)
(2)切片的遍历
func main() {
var slice []int = make([]int,5,6)//5:长度 6:容量
slice[0] = 0
slice[1] = 1
slice[2] = 2
for i:=0;i<len(slice);i++ {
fmt.Print(slice[i])
}
fmt.Println()
for i, v := range slice {
fmt.Println(i,v)
}
}
/*
01200
0 0
1 1
2 2
3 0
4 0
*/
(3)切片的使用
-
切片可以动态增长
-
使用数组初始化时,左含右不含
-
var slice = arr[0:end] --> var slice = arr[:end]
-
var slice = arr[start:len(arr)] --> var slice = arr[start:]
-
var slice = arr[0:len(arr)] --> var slice = arr[:]
-
切片可以继续切片
func main() { var slice1 []int = []int{1,2,3} var slice2 = slice1[1:2] fmt.Println(slice2)//[2] }
-
append内置函数,动态追加
func main() { var slice []int = make([]int, 2, 3) fmt.Println(slice) slice = append(slice, 1) fmt.Println(slice) } /* [0 0] [0 0 1] */
-
切片的拷贝
//拷贝的切片创建新的独立空间 var slice1 []int = make([]int, 2) var slice2 []int = make([]int, 2) copy(slice1,slice2)
(4)切片储存方式
切片类似于指针,是在内存中直接切出一块独立空间(cap),然后在该空间内存储内容(len)。
举个例子:
func main() {
var s []int = make([]int, 2, 3)
fmt.Println(s, len(s), cap(s))
}
//[0 0] 2 3
此时,数据存储方式如下图
append一个数据
func main() {
var s []int = make([]int, 2, 3)
s = append(s, 1)
fmt.Println(s, len(s), cap(s))
}
//[0 0 1] 3 3
继续append
func main() {
var s []int = make([]int, 2, 3)
s = append(s, 1)
s = append(s, 2)
fmt.Println(s, len(s), cap(s))
}
//[0 0 1 2] 4 6
当切片的容量不足以继续append时,会自动增加容量。 在切片的容量小于 1000 个元素时,会成倍地增加容量。当元素个数超过 1000,会每次增加 25%的容量(随着语言的演化,这种增长算法可能会有所改变)。
这次,我们观察数组,根据该数组生成的切片,继续切片得到的切片,以及copy的切片之间的关系
func main() {
var arr = [3]int{1, 2, 3}
var s1 = arr[0:]
var s2 = s1[1:]
var s3 []int = make([]int, 3)
copy(s3, s1)
s2[1] = 9
fmt.Println(arr)
fmt.Println(s1, len(s1), cap(s1))
fmt.Println(s2, len(s2), cap(s2))
fmt.Println(s3, len(s3), cap(s3))
}
/*
[1 2 9]
[1 2 9] 3 3
[2 9] 2 2
[1 2 3] 3 3
*/
可见arr,s1,s2使用的其实是同一个数据,s3使用的是独自的数据
可见,切片可以理解为指针,指向一块单独为该切片开辟的空间,且该空间可以扩大,可以被其他指针指向。