golang中slice底层实现

2019-12-18  本文已影响0人  化蝶飞618

什么是切片

切片就是我们经常所说的动态数组,可以灵活的增加和减少切片内的元素。
常见的切片操作有:reslice、append、copy

切片和数组该如何选择呢?

区别

切片是引用类型,数组是值类型。那么数组在复制和函数传参时候都是值复制。

优缺点

数组作为函数传参,当数组比较大时候往往会造成资源浪费。
切片是引用传递,所以它们不需要使用额外的内存并且比使用数组更有效率。

底层的数据结构

首先切片本身并不是动态数组或者数组指针,它是通过指针引用底层数组,本身是一个只读对象,其工作机制类似数组指针的一种封装。
切片数据结构定义:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

切片的结构体由3部分构成,Pointer 是指向一个数组的指针,len 代表当前切片的长度,cap 是当前切片的容量。cap 总是大于等于 len 的。

创建切片

两种形式:make 创建切片,空切片。

slice := make([]int,4,6)

创建了一个len是4,容量是6的切片。、
字面量也可以创建切片

slice := []int{1,2,3,4,5}

需要注意的是 [ ] 里面不要写数组的容量,因为如果写了个数以后就是数组了,而不是切片了。

var slice []int

切片扩容

一个是扩容时候的策略,还有一个就是扩容是生成全新的内存地址还是在原来的地址后追加。
扩容不像java那样通过负载因子触发,具体策略如下:

切片拷贝

完整复制一个切片,

array := []int{1, 2, 3, 4}
slice := make([]int, len(array))
n := copy(slice, array)
fmt.Println(n,slice)
上一篇 下一篇

猜你喜欢

热点阅读