# 数组与切片
* * * * *
--: 作者:Mick
时间:2018年9月1日
* * * * *
:-: **数组**
* * * * *
#### 数组的定义
数组是一个长度固定类型一致的值数据类型
#### 数组的声明
第一种 Var关键字声明0值初始化
var arr [n]type // n表示数组的长度无符号整形或 ... ,type表示存储任意类型的元素
var arr [10]int // 声明了一个int类型的数组,全部0填充
arr[0] = 42 // 数组下标是从0开始的
arr[1] = 13 // 赋值操作
* * * * *
第二种 数组字面量声明并初始化
arr1 := [5]int{1,2,3} // 最常用
arr2 := [...]int{1,2,3} // 可以省略长度而采用`...`的方式,自动计算填充
arr3 := [...]int{100:100} //索引为99的值是100,其余值是默认值0
arr4 := *[3]int{1,2,3} //指针数组共享值
arr5 := [2][4]int{{1,2,3,4},{5,6,7,8}} //二维数组,2行3列
![](https://box.kancloud.cn/67f730292dfde98b6889029cf83ec7d8_545x190.png)
#### 数组的遍历
func main(){
arr1 := [5]int{0:0,1:1,2:2}
PrintPArr(arr1)
fmt.Println(arr1)
}
func PrintPArr(arr1 [5]int){
for k,v := range arr1{
fmt.Println(k," => ",v)
arr1[k] = k
}
}
//思考值数组 arr1 [5]int 换成 指针数组arr1 *[5]int
#### 数组的总结
长度是数组类型的一部分[1]int 与 [2]int 是不同类型
数组是值拷贝 func printValue(arr [5]int) 与 func printValue(arr *[5]int)
**问题1:如果我不知道数组的长度怎们办
问题2:如果我想改变数组的长度怎么办**
:-: **切片**
* * * * *
#### 切片的定义
切片是一个长度不定类型一致的引用数据类型,底层指向数组的第一个元素
可以按需自动增长和缩小,slice总是指向一个底层array
#### 切片的声明
第一种 Var关键字声明0值初始化
var s []type // 中括号为空,type表示存储任意类型的元素
var s []int // 和声明array一样,只是少了长度
s[0] = 0 // 索引从0开始
* * * * *
第二种 切片字面量声明并初始化
s1 := []byte {'a', 'b', 'c', 'd'}
* * * * *
第3种 使用make函数创建
s := make([]int,10) // []int 表示创建的类型,10 表示容量
* * * * *
#### 切片结构
* * * * *
![](https://box.kancloud.cn/230d6592abb9fc32f8469a30e46ebb4a_675x339.png)
* * * * *
// 从array 或 slice 中获取 slice
array[i,j] // i 开始索引 , j 结束索引 , 范围 [i,j)
* 省略开始索引 ar[:n] =》 ar[0:n]
* 省略结束索引 ar[n:] =》 ar[n:len(ar)]
* 省略前后索引 ar[:] =》ar[0:len(ar)]
* append函数用于切片末尾追加
* len计算切片的长度
* cap计算切片的容量
slice := []int{10,20,30,40,50} // len=4, cap=4
newSlice := slice[1:3]
newSlice = append(newSlice,60)
fmt.Println (slice,newSlice)
fmt.Println(len(slice),cap(newSlice))
* * * * *
思考题
* 什么是切片的长度, 怎么计算
* 什么是切片的容量,怎么计算
slice对应数组的信息,i 起始位置, j 结束位置, k 数组长度
len 获取slice的长度, j - i
cap 获取slice的最大容量, k - i
* * * * *
思考题
* 切片如何扩容,怎么追加或删除元素
* 切片的长度与容量计算方式
* * * * *
![](https://box.kancloud.cn/473b1e9bc30637ba5ddd664bbf801316_426x374.png)
#### 切片扩容深入
1: 什么时候回扩容
append 向slice里面追加一个或者多个元素的时候
* 如果 len(切片长度) > cap(原有的容量) 则切片会进行扩容
* 此切片的底层数据会copy原有的数组,然后进行追加,不影响原有的数组
2: 扩容的规则
* 元素个数 <= 1024 ,容量是2倍增长
* 元素个数 > 1024 , 容量是1.25倍增长
slice := []int{10,20,30,40} // len=5, cap=5
newSlice := append(slice,50)
fmt.Println(slice,newSlice)
#### 举例验证
* 数组是值类型
* 切片是引用类型