切片slice
概念
切片是对数组的一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是数组的一个引用
数组和slice之间有着紧密的联系。一个slice是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,而且slice的底层确实引用一个数组对象。一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。内置的len和cap函数分别返回slice的长度和容量。
长度和容量
基本语法
声明:
var 切片名 []int // []内是没有大小的
一. make()函数
var 切片名 = make([]int, 4, 10) // make(slice类型,长度,容量)
// 第三个参数: 没有容量时默认与长度相等
二. 使用已有数组
var numbers [4]int = {1,2,3}
var 切片名 = numbers[1:3] // 左闭右开 2,3
var 切片名 = []int numbers[0:2]
三. 指定元素
var 切片名 = []float64{1.2, 2.3, 5.6}
var 切片名 []float64 = []float64{2.4, 12.2, 32.9}
// 指定切片索引
var 切片名 = []int{1: 3, 2: 5, 0: 5959}
将切片传递给函数
函数的形参可能是切片,我们需要将数组作为切片传递给参数
func sum(a []int) int {
sum := 0
for i := 0; i < len(a); i++ {
sum += a[i]
}
return sum
}
func main() {
var arr = [4]int{1, 2, 3, 4}
sum(arr[:])
}
数组形参和切片形参
func test01(arr [4]int) {
arr[0]++
}
func test02(arr []int) {
arr[0]++
}
func test03(arr *[4]int) {
// 指针传递,将数组的地址传递给arr,arr是数组指针
(*arr)[0]++ // 将数组指针arr解引用
}
func main() {
var arr1 = [4]int{1, 2, 3, 4}
var arr2 = [4]int{1, 2, 3, 4}
var arr3 = [4]int{1, 2, 3, 4}
test01(arr1)
fmt.Println(arr1)
test02(arr2[:])
fmt.Println(arr2)
test03(&arr3)
fmt.Println(arr3)
}
第一种是直接传递数组,无法对原来的数组进行改变;第二种是切片的方式,切片是引用类型,所以会对原来的数组发生改变;第三种是数组的指针方式,也会对原来的数组改变
空切片和nil切片
空切片
切片的长度是0,那么它是空切片
// 声明一个空切片
var slice1 []int = []int{}
fmt.Printf("%d \n", len(slice1))
// make声明一个空切片
var slice2 = make([]int, 0)
fmt.Printf("%d \n", len(slice2))
nil切片
切片作为引用类型,默认的零值为nil;
nil切片的ptr指针是nil