Go切片的内部实现

描述

切片

Go中提供了一种灵活,功能强悍的内置类型Slices切片(“动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

切片中有两个概念:一是len长度,二是cap容量,长度是指已经被赋过值的最大下标+1,可通过内置函数len()获得。

容量是指切片目前可容纳的最多元素个数,可通过内置函数cap()获得。切片是引用类型,因此在当传递切片时将引用同一指针,修改值将会影响其他的对象。

s := []int {1,2,3 }            //直接初始化切片

s := arr[:]                    //用数组初始化切片

s = make([]int, 3)             //make初始化,有3个元素的切片, len和cap都为3

s = make([]int, 2, 3)          //make初始化,有2个元素的切片, len为2, cap为3

a = append(a, 1)               // 追加1个元素

a = append(a, 1, 2, 3)         // 追加多个元素, 手写解包方式

a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包

不过要注意的是,在容量不足的情况下,append的操作会导致重新分配内存,可能导致巨大的内存分配和复制数据代价。

a = append([]int{0}, a...) 切片头部添加元素。在开头一般都会导致内存的重新分配,而且会导致已有的元素全部复制1次。

因此,从切片的开头添加元素的性能一般要比从尾部追加元素的性能差很多。

//切片是地址传递
func updateSlice(a []int) {
     a[0] = 3
}

func main() {
     //切片
     var a = []int{1, 2, 3}
     c := make([]int, 5)
     copy(c, a)

     updateSlice(c)
     fmt.Println(c)
}
打印
[3 2 3 0 0]

切片的内部实现

切片是一个很小的对象,它对底层的数组(内部是通过数组保存数据的)进行了抽象,并提供相关的操作方法。

切片是一个有三个字段的数据结构,这些数据结构包含 Golang 需要操作底层数组的元数据:

数据结构

这 3 个字段分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量)。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分