1、切片不能直接比较
- 不能使用==操作符来判断两个切片是否含有全部相等元素
- 切片唯一合法的比较操作是和nil比较
- 为nil值的切片长度和容量都是0,且没有底层数组;但是不能说一个长度和容量都是0的切片一定是nil
var a []int //a的长度和容量都是0。a == nil
var b = []int{} //b的长度和容量都是0。b != nil
var c = make([]int,0,0) //c的长度和容量都是0。c != nil
要判断一个切片是否为空,应该用len(s) == 0来判断,而不是 s == nil来判断
2、切片的赋值拷贝
两个切片共享底层数组,所以对一个切片的修改会影响另一个切片的内容
s := make([]int,3)
s1 := s //将s赋值给s1
s1[1] = 200 //修改s1索引为1的值,s和s1共享一个底层数组
fmt.Println(s) //[0,200,0]
fmt.Println(s1) //[0,200,0]
3、切片遍历
切片遍历和数组是一致的,支持索引遍历和for range遍历
a := []int{1,2,3,4}
// 索引遍历
for i := 0;i<len(a);i++{
fmt.Println(a[i])
}
// for range遍历
for index,value := range a{
fmt.Println(index,value)
}
4、append()为切片添加元素
- 可以一次添加多个元素,可以添加多个元素,也可以使用…添加另一个切片中的元素
- append()将元素添加到切片末尾
- 使用原来切片的变量接收返回值
// 添加一个元素
var a []int
a := append(a,10) //[10]
// 添加多个元素
a := append(a,11,22,33) // [11,22,33]
// 添加另一个切片的元素
b := []int{12,13,14}
a := append(a,b...) //[12,13,14]
//使用make创建切片时,用append()添加元素需要注意的事项
a := make([]int,3) // make创建切片时有默认长度就会有默认值:[0,0,0]
a = append(a,10)
fmt.Println(a) //append()再添加元素时是在默认值后添加,而不是覆盖默认值:[0,0,0,10]
- 当底层数组容量不能容纳新增元素时,切片会自动扩容
- 此时切片指向的底层数组就会更换,会自动申请一个新数组,大小为原来切片容量的2倍,并将原来切片的值复制到新的数组上,切片就与原数组脱离,指针指向新数组
- 扩容操作一般发生在append()函数调用时,所以一般用原切片变量接收函数返回值
5、copy()函数复制切片
把一个切片复制到另一个切片上
copy(destSlice, srcSlice)
- destSlice: 目标切片
- srcSlice: 数据来源切片
// 使用场景
var a = [10000]int{3,4,5}
s := a[0:3]
fmt.Println(s) //将数组a中的一小部分切片赋值给了s,但s也是基于很大的数组a,使用s内存占用很高
//这时候可以把s copy到另一个基于小数组的切片s1上
s1 := make([]int,3) [0,0,0]
copy(s1,s)
fmt,Println(s1) // [3,4,5] 以后使用s1操作,节约内存
两个切片不一样长时的复制
s := []int{1,2}
s1 := make([]int,5)
copy(s1,s)
fmt.Println(s1) //[1 2 0 0 0] 以0填充
6、切片中删除元素
- go语言没有删除切片元素的专用方法,通过切片本身的特点删除元素
- 以被删除元素为分界点,再利用append将前后两个部分内存重新连接起来
// 如果要删除切片s中的一个元素,被删除的元素索引为index
s = append(s[:index],s[index+1:])
a := []int{11,22,33,44,55,66}
// 删除索引为3的元素44
a1 := append(a[:3],a[4:]...)
fmt.Println(a1) // [11 22 33 55 66]
7、多维切片
var s [][]int
// 定义并初始化
var s [][]int=[][]int{{1,1,1,1},{2,2,},{3,3,3,3}}
// 通过make初始化,内层的切片没有初始化,要使用内层切片就要初始化
var s =make([][]int,3,4)
s[0]=make([]int,5,6) // 初始化内层索引为0的切片
s[0][0]=99
fmt.Println(s) // 99
s[1][0]=99
fmt.Println(s) //报错,内层索引为1的切片没有初始化
//循环多维切片(基于索引,基于迭代)
var s [][]int=[][]int{{1,1},{2,2},{3,3,3,3}}
for i:=0;i<len(s);i++{
for j:=0;j<len(s[i]);j++{
fmt.Println(s[i][j])
}
}
for _,v:=range s{
for _,v1:=range v{
fmt.Println(v1)
}