go语言中的slice,相当于java中的ArrayList,底层都是数组实现的。
一、slice声明
1. 先声明,然后再使用
var s []int
s = append(s, 1)
fmt.Println(s)
2.直接初始化
s := []int{1, 2, 3}
s = append(s, 4)
fmt.Println(s)
3.使用make声明并且初始化(常用)
s := make([]int, 0, 5)
fmt.Println(s) //结果为 []
s1 := make([]int, 5)
fmt.Println(s1) //结果为[0 0 0 0 0],自动初始化五个元素放入s1
make([]int, 0, 5), 0是slice的长度, 5是slice的容量。
make([]int, 5), slice的长度和容量都是5。
二、slice 常用方法
1. 获取长度
s := make([]int, 0, 5)
fmt.Println(len(s)) //结果为0
2. 获取容量
s := make([]int, 0, 5)
fmt.Println(cap(s)) //结果为5
3. 追加元素
s := make([]int, 0, 5)
s = append(s, 1)
s = append(s, 2)
s = append(s, 3)
s = append(s, 4)
s = append(s, 5)
s = append(s, 6)
fmt.Println(s) //结果为[1 2 3 4 5 6]
4. 遍历
可以方便的使用range遍历slice, i为索引, v为值
s := make([]int, 0, 5)
s = append(s, 1)
s = append(s, 2)
s = append(s, 3)
s = append(s, 4)
s = append(s, 5)
s = append(s, 6)
fmt.Println(s) //结果为[1 2 3 4 5 6]
for i, v := range s {
fmt.Println(fmt.Sprintf("index: %d, valued: %d", i, v))
}
三、slice原理
slice源码,在src/runtime/slice.go
1. 底层存储
array为指向底层数组的指针, len为slice的长度, cap为slice的容量。
2.扩容机制
当前需要容量如果小于当前的容量,无需扩容;否则2倍扩容
当前需要容量大于当前容量2倍,直接扩容至当前容量
如果需要的容量小于256,直接就是2倍扩容
如果需要的容量大于256,则1.25x扩容直到容量足够