目录
@
简介
- slice本身不是数组,它指向底层的数组
- 是作为边长数组的替代方案,可以关联底层数组的局部或者全部
- 为引用类型,类似指针
- 可以直接创建或从底层数组获取生成,也可以用=直接从别的slice赋值
- 使用len() 获取元素个数,cap()获取容量
- 一般使用make()创建,make([]T,len,cap), 其中cap可以省略,此时和len的值相同,len表示存数的个数,cap表示容量
- 如果len超过了cap,会重新分配内存cap,然后翻倍
- 如果多个slice指向了同一个底层数组,其中一个的值改变会影响全部
声明赋值和初始化
方法一
func main(){
a := [10]int{0,1,2,3,4,5,6,7,8,9}
fmt.Println(a)
//定义slice,[]里面不加任何东西
var s1 []int
s1 = a[5:10]
//索引5到10,不包括10
s2 := a[:5]
//取下标从0到5,不包括5
s3 := a[5:]
s4 := a[5:len(a)]
//从下标5开始,到最后一个元素,两式相同
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
fmt.Println(s4)
}
/*
> Output:
command-line-arguments
[0 1 2 3 4 5 6 7 8 9]
[5 6 7 8 9]
[0 1 2 3 4]
[5 6 7 8 9]
[5 6 7 8 9]
*/
方法二
func main(){
s1 := make([]int, 3, 10)
fmt.Println(len(s1),cap(s1))
}
//3,10
- slice的len就是当前的元素个数,cap是在对应数组中,开始位置到最后一个的长度
func main(){
a := [9]byte{'a','b','c','d','e','f','g','h','i'}
sa := a[2:5]
fmt.Println("sa: ",len(sa),cap(sa),string(sa))
sb := make([]byte,3,10)
sb = sa[3:5]
fmt.Println("sb: ",len(sb),cap(sb),string(sb))
}
/*
> Output:
command-line-arguments
sa: 3 7 cde
sb: 2 4 fg
*/
Reslice
- reslice就是对一个slice进行slice
- reslice时索引以被slice的切片为准
- 索引不可以超过被slice的切片的cap()值
- 索引越界不会导致底层数组的重新分配,而是引发错误
append函数
- 可以在slice尾部追加元素
- 可以将一个slice追加在另一个slice尾部
- 如果追加之后,最终长度未超过追加到slice的容量,就返回原始slice
- 否则,就将重新分配数组(cap变成二倍)并拷贝原始数据
- append增加了cap后,通过别的slice改变的元素,在这个slice里面不会改变,因为这个slice已经指向了别的新数组,meanwhile,改了这个slice也不回影响别的slice和原先的数组
func main(){
a := make([]int,3,6)
fmt.Printf("a: %p
",a)
s1 := append(a,1,2,3)
fmt.Printf("s1: %v %p %d
",s1,s1,cap(s1))
fmt.Printf("a: %v %p %d
",a,a,cap(a))
s1 = append(s1,1,2,3)
fmt.Printf("s1: %v %p %d
",s1,s1,cap(s1))
}
/*
> Output:
command-line-arguments
a: 0xc042072030
s1: [0 0 0 1 2 3] 0xc042072030 6
a: [0 0 0] 0xc042072030 6
s1: [0 0 0 1 2 3 1 2 3] 0xc042046060 12
*/
- append增加了cap后,通过别的slice改变的元素,在这个slice里面不会改变,因为这个slice已经指向了别的新数组,meanwhile,改了这个slice也不回影响别的slice和原先的数组
func main(){
//全是slice
a := []int{1,2,3,4,5}
sa := a[1:5]
sb := a[1:5]
sb=append(sb,1,3,4,5,3,2,2,2)
sb[2]=99
fmt.Println(sb,sa)
}
/*
> Output:
command-line-arguments
[2 3 99 5 1 3 4 5 3 2 2 2] [2 3 4 5]
*/
copy函数
- copy(a,b), 把b拷贝到a里面
- 被拷贝操作的长度由短的哪一方决定
func main(){
a := []int{1,2,3,4,5}
b := []int{7,8,9}
c := []int{11,22,333,44,55,66,77}
copy(b,a)
copy(c[2:4],a[1:3])
fmt.Println(b,c)
}
/*
> Output:
command-line-arguments
[1 2 3] [11 22 2 3 55 66 77]
*/