创建Slice
切片(Slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型).这个片段可以是整个数组.
func main() {
arr := [...]int{0,1,2,3,4,5,6,7}
a := arr[2:6]
fmt.Println("a =>", a)
a0 := arr[:6]
fmt.Println("a0 =>", a0)
a1 := arr[2:]
fmt.Println("a1 =>", a1)
a2 := arr[:]
fmt.Println("a2 =>", a2)
}
Slice属于半开半闭区间的,包头不包尾,:左右两边不写,相当于从下标0开始,到最后一个元素结束
slice作为参数
func main() {
arr := [...]int{0,1,2,3,4,5,6,7}
a1 := arr[2:]
fmt.Println("a1 =>", a1)
updateSlices(a1)
fmt.Println("arr =>", arr)
}
func updateSlices(s []int){
s[0] = 100;
}
- go语言一般不会使用数组作为参数,大多数情况下都是使用切片
- Slice本身没有数据的,是对底层array的一个view.
- 对Slice中元素的修改会影响array的元素
Reslice
func main() {
arr := [...]int{0,1,2,3,4,5,6,7}
s := arr[2:]
fmt.Println("s =>",s)
s = s[:5]
fmt.Println("s =>",s)
s = s[:3]
fmt.Println("s =>",s)
}
- slice上面可以再建立slice
- 这些不同的slice都是view的同一个array
Slice的扩展
func main() {
arr := [...]int{0,1,2,3,4,5,6,7}
s1 := arr[2:6]
fmt.Println("s1 =>",s1)
s2 := s1[3:5]
fmt.Println("s2 =>",s2)
}
- s2把不属于s1的元素6也取出来了,说明Slice是可以进行扩展的,但是如果直接使用s1[4]还是会索引越界
Slice的实现
func main() {
arr := [...]int{0,1,2,3,4,5,6,7}
s1 := arr[2:6]
fmt.Printf("s1 =%v, len(s1)=%d, cap(s1)=%d\n",s1,len(s1),cap(s1))
s2 := s1[3:5]
fmt.Printf("s2 =%v, len(s2)=%d, cap(s2)=%d\n",s2,len(s2),cap(s2))
fmt.Println(s2[:4])
}
Slice的操作
append
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := arr[2:6]
fmt.Printf("s1 =%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))
s2 := s1[3:5]
fmt.Printf("s2 =%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3 =>", s3)
fmt.Println("s4 =>", s4)
fmt.Println("s5 =>", s5)
fmt.Println("arr =>", arr)
}
- 添加元素时如果超越cap,系统会重新分配更大的底层数组(s4,s5不再是对arr的view,是系统分配更大的底层数组的view);原来的数组如果有引用,它就还在,如果没有引用就会被垃圾回收
- 由于值传递的关系,必须接收append的返回值
- s = append(s,val)
Slice的扩容
func printSlice(s []int){
fmt.Printf("len=%d,cap=%d\n",len(s),cap(s))
}
func main() {
var s [] int
fmt.Println(s)
for i:=0; i<10;i++{
printSlice(s)
s = append(s,i)
}
fmt.Println(s)
}
当len为0时,cap也为0,当len开始添加元素时,cap从开始扩容为1,以后每次添加不了元素时都进行2倍的扩容
func main() {
s1 := []int{2,4,6,8}
printSlice(s1)
s2 := make([]int,16)
printSlice(s2)
s3 := make([]int, 16, 32)
printSlice(s3)
}
func printSlice(s []int){
fmt.Printf("%v len=%d,cap=%d\n",s,len(s),cap(s))
}
CopySlice
func main() {
arr1 := []int{1,3,5,7,9}
arr2 :=make([]int,10);
printSlice(arr2)
copy(arr2,arr1)
printSlice(arr2)
}
func printSlice(s []int){
fmt.Printf("%v len=%d,cap=%d\n",s,len(s),cap(s))
}
删除元素
删除中间的元素
func main() {
arr1 := []int{1,3,5,7,9}
printSlice(arr1)
arr1 = append(arr1[:1],arr1[2:]...)
printSlice(arr1)
}
func printSlice(s []int){
fmt.Printf("%v len=%d,cap=%d\n",s,len(s),cap(s))
}
删除头元素
func main() {
arr1 := []int{1,3,5,7,9}
printSlice(arr1)
head := arr1[0]
arr1 = arr1[1:]
printSlice(arr1)
fmt.Println("head =>",head)
}
func printSlice(s []int){
fmt.Printf("%v len=%d,cap=%d\n",s,len(s),cap(s))
}
删除尾元素
func main() {
arr1 := []int{1,3,5,7,9}
printSlice(arr1)
tail := arr1[len(arr1)-1]
arr1 = arr1[:len(arr1)-1]
printSlice(arr1)
fmt.Println("tail =>",tail)
}
func printSlice(s []int){
fmt.Printf("%v len=%d,cap=%d\n",s,len(s),cap(s))
}
|