跳到主要内容

Go 切片底层数组的重新分配情况与示例

· 阅读需 2 分钟
素明诚
Full stack development

扩容操作

当使用 append 向切片追加元素,且追加后的总元素数量超出了切片的原始容量时,Go 会自动重新分配一个更大的底层数组。

slice := []int{1, 2, 3}
slice = append(slice, 4, 5, 6, 7) // 原始容量可能不足以存放所有元素,触发重新分配

从 nil 切片

nil 切片进行 appendnil 切片进行 append 操作时,由于 nil 切片没有底层数组,因此会分配一个新的数组。

var slice []int
slice = append(slice, 1) // 从 nil 切片开始,分配新的底层数组

切片截取后再扩容

如果对一个切片进行截取操作,然后基于这个截取的结果进行 append 操作,并且所需容量超过了截取切片的容量,这同样会触发重新分配。

original := []int{1, 2, 3, 4, 5}
subSlice := original[:2] // 容量仍然是 5
subSlice = append(subSlice, 6, 7, 8, 9, 10, 11) // 容量超载,需要重新分配

显式使用 make 指定初始容量

当使用 make 创建切片时,可以指定一个初始容量,这种方式创建的切片将拥有独立的底层数组。

slice := make([]int, 0, 10)  // 创建一个初始容量为 10 的空切片

通过 copy 创建新切片

使用 copy 函数可以创建一个完全独立的切片副本,该副本将拥有自己的底层数组。

original := []int{1, 2, 3}
clone := make([]int, len(original))
copy(clone, original) // clone 现在有了一个完全独立的底层数组

求赞~