用于表示多个数据,可以理解为动态数组。
切片是Go中重要的数据类型,每个切片对象内部都维护着:数组指针、切片长度、切片容量三个数据。
type slice struct {
array unsafe.Pointer
len int
cap int
}
在向切片中追加的数据个数大于容量时,内部会自动扩容且妹子扩容当前容量的2倍
当容量超过1024时,每次扩容只增加1/4容量(源码中体现)
runtime/slice.go
// 创建切片
var nums []int // 容量默认为0,每次添加内容的时候,都要耗费资源去扩容,
// 创建切片
// make 只用于切片、字典和channel
var users = make([]int, 2, 5) // 容量=5 长度=2 且存储的值是int类型的默认值
// 创建切片
var data = []int{11, 22, 33}
var v1 = new([] int) // 容量=0 长度=0 存储的数据也是空的
// 不同的是 返回的类型是一个 切片的指针类型
// 指针类型 => 指向的是nil
var v2 *[]int
v1 := make([]int, 1, 3) // 默认长度=1 容量=3 默认值为0
fmt.Println(len(v1), cap(v1)) // 获取长度和获取容量
v2 := make([]int, 3) // 容量=3 长度默认为3 初始值是int的默认值
v1 := make([]int, 1, 3)
v2 := append(v1, 99) // 返回一个新的切片
fmt.Println(v1) // [0]
fmt.Println(v2) // [0, 99]
v1[0] = 66
fmt.Println(v1) // [66]
fmt.Println(v2) // [66, 99]
v1和v2的 内存地址是一样的
需求:有一个切片,请往一个切片中追加一个数据
v3 := make([]int, 1, 3)
v3 = append(v3, 999) // [0, 999]
下面的v4和v5最终扩容后内存是指向不同的地方
v4 := []int{11, 22, 33}
fmt.Println(len(v4), cap(v4)) // 3 3
v5 := append(v4, 44)
fmt.Println(len(v4), cap(v4)) // 3 3
fmt.Println(len(v5), cap(v5)) // 4 6
通过len
和cap
方法获取切片的长度和容量
v1 := []string{"wujie", "无解", "五天"}
// 取数据
v1[0]
v1[1]
v1[2]
v2 := make([]int, 2, 5) // 初始化2个元素,容量时5
v2[0] // 0
v2[1] // 0
v2[2] // 报错 索引的位置不能大于它内部的长度
// 修改值
v2[0] = 99
v1 := []int{11, 22, 33, 44, 55, 66}
v2 := v1[1:3] // 取切片的第一个索引开始到第三个索引 1 <= 范围 < 3
v3 := v1[1:] // 从1开始到索引的最大程度
v4 := v1[:3] // 从第一个开始到第三个索引 11 22 33
// 注意:通过切片切出来的数据和原切片内部存储数据地址相同
注意:通过切片切出来的数据和原切片内部存储数据地址相同
v1 := []int{11, 22, 33, 44, 55, 66}
v2 := append(v1, 77)
v3 := append(v1, 77, 99, 99)
v4 := append(v1, []int{100, 200, 300}...) // 追加另外一个切片,必须加上3个点,将切片的里的每一个元素拿到,分别追加到切片的后边,得到的新的切片赋值给v4
默认是没有删除的操作的