这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记
上一篇的内容地址为:juejin.cn/post/710577…
四、数组与切片
(1) 数组
在go中,我们很少会用到数组,但是go的切片是通过数组实现的,所以我们也要看一下go数组的一些规则。数组是具有相同唯一类型的一组以编号且长度固定的数据项序列(这是一种同构的数据结构);这种类型可以是任意的原始类型例如int、string或者自定义类型。数组长度必须是一个常量表达式,并且必须是一个非负整数。数组长度也是数组类型的一部分,所以 [2]int 和 [3]int 是属于不同类型的。
我们如果想要声明一个长度为10的int类型的数组,如下所示:
var arr1 [10]int
在go中,数组是一种值类型,需要区别*[3]int与[3]int是两种不同的类型。我写了一个程序如下:
package main
import (
"fmt"
)
func main() {
arr1 := [3]int{1,2,3}
arr2 := arr1 //arr2是拷贝了arr1
arr2[0] = 111
fmt.Println(arr1[0])
fmt.Println(arr2[0])
arr3 := &arr1 //arr3是指针类型*[3]int
arr3[0] = 222
fmt.Println(arr1[0])
fmt.Println(arr3[0])
}
最终的结果如下:
1
111
222
222
可以看到,普通类型的是拷贝了过去,而指针类型的是使用了同一处的值,所以修改arr3会影响到arr1。如果我们想要初始化,这两种方式可以这么写:
var arr1 [3]int //返回值类型
var arr2 = new([3]int) //返回指针类型
(2) 切片
与数组不同,切片是对一个数组的引用,因而切片是一个引用类型。
切片的声明方式与初始化方式为:
var slice1 []int
slice2 := []int{1, 2, 3}
slice3 []int = make([]int, 3, 3)
//slice3 []type = make([]type, len, cap)
切片有两个值得注意的参数,一个是len(s)获取其长度,另一个是cap(s)获取其容量。切片的长度可以改变,但是不能大于其容量,因而0<=len(s)<=cap(s)总是成立的。
当我们要遍历一个数组,我们可以使用之前提过的for-range结构:
slice1 := []int{9, 8, 7}
for i, value := range slice1 {
fmt.Printf("下标为%d, 值为%d\n",i,value)
}
结果为:
下标为0, 值为9
下标为1, 值为8
下标为2, 值为7