切片—动态分配大小的连续空间
Go语言切片内部结构包含地址、大小和容量。切片一般用于快速地操作一块数据集合。如果将数据集合比作切糕的话,切片就是你想要的那一块。
应用:因为Go语言的数组长度不可变,在一些特殊的场景就不太使用。切片就类似于动态数组(C++中的vector),长度不固定,且可以扩充元素。
可以以如图所示理解:
- 数组或者切片生成新的切片
切片默认指向一段连续内存区域,可以是数组,也可以是切片本身。
从连续内存区域生成切片,数组生成切片,代码如下:
var a = [3]int{1,2,3}
fmt.Println(a,a[1:2])
输出:[1,2,3] [2]
- 取出元素的数量=结束位置-开始位置
- 取出元素不包含结束位置对应的索引,切片最后一个元素使用slice[len(slice)]获取
- 当缺省开始位置时,表示从连续区域开头到结束位置;
- 当缺省结束位置时,表示从开始位置到整个连续区域末尾;
- 两者同时缺省时,与切片本身等效;
- 两者同时为 0 时,等效于空切片,一般用于切片复位。
示例:从指定范围中生成切片
package main
import (
"fmt"
)
func main() {
var highRiseBuliding [30]int
//赋值
for i := 0; i < 30; i++ {
highRiseBuliding[i] = i + 1
}
//区间
fmt.Println(highRiseBuliding[10:15])
//中间到尾部的所有元素
fmt.Println(highRiseBuliding[20:])
//开头到中间的所有元素
fmt.Println(highRiseBuliding[:15])
}
输出结果:
表示原有的切片:
a := []int{1,2,3}
fmt.Println(a[:])
//a[:]切片与a保持一致
重置切片,清空元素
a :=[0:0]
2.声明切片
和数组很像,但是注意区别;
var name []T
//声明整型切片
var numList []int
//声明字符串切片
var strList []int//切片没有元素
使用make()函数动态构造切片
make([]T,size,cap)
- 注意,使用make()创建的切片一定进行了内存分配,但是给定开始和结束位置的切片只是将切片指向将分配好的内存区域。
3.使用append()函数为切片添加元素
当空间不足时,切片会进行"扩容",容量的扩展按2倍数扩充。操作往往发生在append()函数调用时。
例如:
var numbers []int
for i :=0 ;i<10;i++{
numbers =append(numbers,i)
}
4.复制切片到另一个切片
使用copy()函数可以实现。格式如下:
copy(destSlice,srcSlice []T) int
//copy的返回值表示实际发生复制的元素个数。
示例:
package main
import (
"fmt"
)
func main() {
const elementCount = 1000
//创建元素切片
srcData := make([]int, elementCount)
//将切片赋值
for i := 0; i < elementCount; i++ {
srcData[i] = i
}
//引用切片数据
refData := srcData
//创建新的切片空间
copyData := make([]int, elementCount)
//复制到新的切片空间
copy(copyData, srcData)
//修改第一个数据
srcData[0] = 999
fmt.Println(refData[0]) //值会变
fmt.Println(copyData[0])//因为数据是复制的,且开辟新的空间,所以值不变
}
5.从切片中删除元素
Go语言中并没有对删除切片提供专用的语法或者接口,需要使用切片本身的特性删除。
示例:
func main() {
var number []int = make([]int, 6)
for i := 0; i < 6; i++ {
number[i] = i
}
fmt.Println(number)
//删除指定位置
index := 2
//查看删除位置之前的元素和之后的元素
fmt.Println(number[:index], number[index+1:])
//将这两段拼接
number = append(number[:index], number[index+1:]...)
//...表示将其追加到number的后面
fmt.Println(number)
}
输出: