go基础6-切片
go的数组长度是不可变的 数组长度是数组内置的一个常量 无法对数组做增删操作
go语言提供了切片 支持动态增删操作
1 切片的定义
切片字面量中只有元素类型 没有长度
var slice []string = []string{"a","b","c"}
创建切片方法 三种 基于数组 基于切片 和直接创建
1 基于数组
months = [...]sring{"a","b","c","d"}//定义数组
//基于数组创建切片
n := months[1:2] //2表示长度
m :=months[1:3]
c := months[2:3]//{"b","c"}
通过 array[start:end] 这样的方式基于数组生成切片
all := months[:]//
fisrtshalf :=[:2]//前半部分
half := [2:]//包含从第二个元素开始
切片底层引用了一个数组 由三部分构成 --指针 长度 容量 容量是切片起始位置到底层数组结尾的位置 s :=a[3:6]
获得容量函数 cap(s)
fmt.Println(cap(s))
fmt.Println(len(s))
2基于切片
b:=moths[:2]
c :=b[:1] 会受到数组容量限制 虽然是基于切片 但是本质还是基于数组
3 直接创建 make
创建一个初始长度为5的整型切片
a := make([]int,5)
创建一个初始长度为5 容量为10的切片 第三个参数定义容量
b := make([]int,5,10)
直接创建并初始化包含5个元素的切片 容量和长度都是5
c := []int{1,2,3,4,5}
使用直接创建方式创建切片时候 go底层还是会有一个匿名函数被创建 然后调用基于数组创建切片的方式返回切片 所以
切片都是基于数组 切片可以看做是操作数组的指针
二 遍历切片
for i:=0;i<len(summer);i++{
fmt.Println("summer[i] = ",summer[i])
}
for _,v := range summer{
fmt.Println(v)
}
1 动态增加元素
切片支持动态增加元素 还可以在容量不足的情况下自动扩容
元素的个数是切片的实际长度 而可分配的存储空间就是切片的容量
一个切片的容量初始值根据创建方式不同而不同
1对于基于数组和切片的切片而言 默认容量是切片起始索引到对应底层数组的结尾索引
2对应内置make 函数创建的而言 没有指定容量的情况下 默认容量和切片长度一致
cap 容量行数 len() 长度函数
var old = make([]int,5,10)
fmt.Println(len(old))//5
fmt.Println(cap(old))//10
append()函数向切片追加
old 目前是这样 的 {0,0,0,0,0}
$new := append(old,1,2,3)
new {0,0,0,0,0,1,2,3}
append的第二个参数是一个不定参数 可以添加多个 还可以切片
appendSlice :=[]int{1,2,3,4,5}
old := append(old,appendSlice...) //注意末尾的。。。 不能省略
自动扩容
如果追加的元素超过old的默认容量 则会自动扩容
new := append(old,1,2,3,4,5,6,7)
自动扩容的容量会翻倍 比如原来的容量是10 扩容之后是20 当原切片长度大于或者等于1024时候 容量会以1.25倍扩容
内容复制
copy(z ,y) 右边复制到左边
如果2个切片不一样大 就会按照其中较小的那个切片的元素个数进行复制
y := []int{1,2,3,4,5}
z:= []int{6,7,8}
copy(z,y) //1,2,3
copy(y,z) //6,7,8,4,5
动态删除元素
通过切片的切片实现
slice3 := []int{1,2,3,4,5,6,7,8,9,10}
//删除尾部的5个元素
slice := slice3[:len(slice3)-5]
slice ;= slice3[5:]//删除头部的5个元素
还可以使用append copy 实现切片元素的删除
slice10 := []int{1,2,3,4,5,6,7,8,9,10}
append(slice10[:0],slice3[3:]...)//删除开头的三个元素
数据共享的问题
type slice struct{
array unsafe.Pointer//
len int
cap int
}
在结构体中使用指针存在不同实例订单数据共享问题
slice1 := []int{1,2,3,4,5,6}
slice2 := slice[1:3]
slice2[1] = 6;
slice [1,2,6,4,5]
slice [2,6]
slice2基于slice1创建的 他们的数组指针指向同一个数组 修改slice2会同步slice1 因为修改的是同一份内存数据
解决方案
使用append函数 因为append函数执行扩容的时候会重新分配内存 如果初始容量没有进行扩容 使用append函数是无效的