##数组
定义
数组是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。初始化后数组长度是固定的,无法修改其长度。当作为方法的入参传入时將复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分。
初始化
- 长度为5的数组,其元素值依次为:1, 2, 3, 4, 5
[5]int{1, 2, 3, 4, 5}
- 长度为5的数组,其元素值依次为:1, 2, 0, 0, 0. 在初始化时没有指定初值的元素將会赋值为其元素类型的默认值,int是0,string是““
[5]int{1, 2}
- 长度为5的数组,其长度是根据初始化时指定的元素个数决定的
[...]int{1, 2, 3, 4, 5}
- 长度为5的数组,其元素值依次为:0, 0, 1, 2, 3. 在初始化时指定了2, 3, 4索引中对应的值:1, 2, 3
[5]int{2:1, 3:2, 4:3}
- 长度为5的数组,其元素值为:0, 0, 1, 0, 3. 由于指定了最大索引4对应的值为3, 根据初始化的元素个数确定其长度为5
[...]int{2:1, 4:3}
切片
定义
切片基于数组构建,但是提供更强的功能。切片的存储结构依次是底层数组的指针、切片长度、切片容量、切片数据。切片长度是指已经被赋过值的最大下标+1, 可通过len()获取。容量是指切片目前可容纳的最多元素个数,可通过cap()获取。切片是引用类型,而且切片的长度和容量可以修改,当切片的容量发生变化时,可能会重新分配内存,使得切片和原底层数组的关联断开
初始化
- 直接初始化,[]表示是切片类型,初始化值依次是1, 2, 3. 其cap=len=3
s := []int{1, 2, 3}
- 通过数组或其它切片初始化,是其的引用
s := arr[startIndex:endIndex]
- 通过make()初始化,可指定len和cap
切片重新分配内存,导致切片和原底层数组关联断开的情况需要特殊注意,考虑如下代码:s := make([]int, len, cap)
执行后的输出结果是arr1 := [3]int{1, 2, 3} arr2 := [3]int{1, 2, 3} sli1 := arr1[:1] sli2 := arr2[:1] sli1[0] = 0 sli2[0] = 0 sli1 = append(sli1, 5) sli2 = append(sli2, 5, 5, 5) fmt.Println("arr1: ", arr1) fmt.Println("arr2: ", arr2) fmt.Println("sli1: ", sli1) fmt.Println("sli2: ", sli2)
arr1: [0 5 3]
arr2: [0 2 3]
sli1: [0 5]
sli2: [0 5 5 5]
对切片sli1的append操作实际并没有重新分配内存,它还是原数组的引用,所以对sli1的append操作仍而应用到了数组arr1上;而对切片sli2的append操作,重新分配了内存,使得它和原数组的关联断开了,所以对sli2的append操作并没有影响到数组arr2
数组与切片区别
数组长度不可变,切片长度和容量都可变
数组的长度在初始化时就会确定下来,而切片的长度可以动态变化
数组是值类型,而切片是引用类型
用一段代码说明一下
func testArr(arg [3]int) {
arg[0] = 0
fmt.Println("testArr: ", arg)
}
func testSli(arg []int) {
if len(arg) == 0 {
arg = append(arg, 0)
} else {
arg[0] = 0
}
fmt.Println("testSli: ", arg)
}
func main() {
arr := [3]int{1, 2, 3}
fmt.Println("before testArr(): ", arr)
testArr(arr)
fmt.Println("after testArr(): ", arr)
sli := arr[:]
fmt.Println("befor testSli(): ", sli)
testSli(sli)
fmt.Println("after testSli(): ", sli)
}
执行后程序输出
before testArr(): [1 2 3]
testArr: [0 2 3]
after testArr(): [1 2 3]
befor testSli(): [1 2 3]
testSli: [0 2 3]
after testSli(): [0 2 3]
testArr()函数对传进去的arr参数的修改,并没有对arr变量生效,而testSli()函数对sli变量的修改写回到了sli变量
有疑问加站长微信联系(非本文作者))
