Go语言中slice底层原理!
前言
Go的面试技术点!用于记录的学习复习总结!
一、Go 语言中Slice切片?
Slice 是一种动态的数组,它基于底层数组实现。一个Slice由三部分组成:指向底层数组的指针、Slice当前的数组长度和底层数组的容量
type slice struct {
array unsafe.Pointer // 指向底层数组
len int // 长度
cap int // 容量
}
二、Go 语言中Slice扩容的原理!
Slice 的底层原理实现基于数组,当我们使用make创建一个slice的时候,Go会在内存中创建一个新的数组,并返回这个数组的一个slice。当使用append函数给slice添加元素时,若这个底层数组容量不足时,会自动扩容(当cap小于1024容量,扩容直接在原有的基础上翻一番 cap*2;当cap大于1024容量,在原有的基于上 cap*1.25倍),并重新分配一段更大的连续内存,然后将数据复制到新的内存空间中去,然后添加新元素。
注意:此时,底层数组的地址发生了变化,原有的slice和新的slice索引同一个数组,但却有两个不同的底层数组(扩容添加元素后,数组的长度发生了变化)。
如果切片的容量远远大于实际的需求的哇,有还可能进行缩容来释放多余的空间,以节省内存!
总结
注意:由于slice内部包含指向底层数组的指针,因此在我们传递slice参数时,程序并不会复制整个数组,二只会传递指向该数组的指针、长度和容量等信息。这使得slice可以轻松快速地作为函数进行传递,同时也是得切片具有高效灵活的特性。
func main() {
nums := make([]int, 4)
nums[0] = 2
slice1(nums)
fmt.Println(nums) //[1 0 0 0]
}
func slice1(nums []int) {
nums[0] = 1
}