问:切片是什么结构?
slice组成
slice 由三个部分组成:
data:元素存哪里 len:存了多少个元素 cap:可以存多少个元素
初始化int切片
var ints []int
初始化变量ints,data=nil,len=0,cap=0
var ints []int = make([]int,2,5)
data 指向第一个元素,长度为2.且都为0,最大容量为5
在此基础上append:
PS:超出容量的append,会使cap翻倍(具体规则:1.如果扩容前容量翻倍<所需最小容量=> 新容量 = 所需最小容量;2.否则:长度小于1024直接翻倍,大于等于1024,扩容1/4)
PS:超出长度的读取不被允许
var ints []int = make([]int,2,5)
ints = append(ints,1)
[0,0,1]
初始化字符串切片
ps := new([]string)
new一个字符串切片同样会分配这三部分结构,但它不负责底层数组的分配,所以data=nil,len=0,cap=0
new的返回值就是slice结构的起始地址,所以ps呀就是个地址
此时,这个slice变量还没有底层数组,所以下面这个操作不被允许:
(*ps)[0]="eggo"
通过append的方式添加元素:
*ps = append (*ps,"eggo")
append会给slice开辟底层数组,data=底层数组起始地址+字节长度=4,len=1,cap=1
数组与切片
data不是必须指向数组开头
arr := [10]int{0,1,2,3,4,5,6,7,8,9}
var s1 []int = arr[1:4]
var s2 []int = arr[7:]
s1的元素使arr索引1到4,左闭右开(data:&arr[1],len:3,cap=9(从data开始到底层数组结束))
.
s2的元素使arr索引7到9,左闭右开(data:&arr[7],len:3,cap=3(从data开始到底层数组结束))
slice访问和修改的都是底层数组的元素,s1可以通过append来拓展(未超过底层数组时候,在原底层数组上修改,超过后则开辟新数组并修改)。
此时给s2添加元素,会开辟新数组,将原来的值copy过来,容量翻倍cap=6