slice
在切片的 index 位置插入元素
copy(res[index+1:],res[index:]) // 将 slice 从 index 位置后移,空出 index 位置
res[index]=value
底层
type slice struct {
// 指针指向底层的数组
array unsafe.Pointer
// 当前切片所使用的长度
len int
// 底层数组的长度
cap int
}

在复制切片时,底层的数组也被复制,导致在新的复制生成的切片发生扩容前,其内部的 array unsafe.Pointer
与原切片的 array 指针指向的是同一底层数组,此时对newSlice 的修改会影响oldSlice——>发生扩容后则不会
扩容算法:
-
所需最小 MinCap>2*oldCap newCap=Mincap
-
原 slice 长度 len<1024则两倍扩容
-
原 slice 长度len>1024 则 1.25 倍扩容
-
最后进行内存对齐
// 扩容算法
newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
if old.len < 1024 {
newcap = doublecap
} else {
// Check 0 < newcap to detect overflow
// and prevent an infinite loop.
for 0 < newcap && newcap < cap {
newcap += newcap / 4
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
if newcap <= 0 {
newcap = cap
}
}
}
Tips:
- 打印
%p
可以输出 slice 指向的底层数组的地址 - 创建 slice 时候使用
mallocgc
函数分配内存,如果创建的 size==0则返回固定的 slice 的底层数组地址- 使用
s:=make([]int,0)
和s:=[]int{}
创建则 len==0 默认地址 - 使用
var s []int
则底层数组指针为 nil
- 使用
逆序slice
// 辅助空间
resTrue:=make([] int,len(res))
for index:=range res {
resTrue[index]=res[len(res) - 1-index]
}
// 原地逆序
for i:=0;i<len(res)>>1; i++{
res[i],res[len(res) - 1-i]=res[len(res) - 1-i],res[i]
}