当前位置:诺佳网 > 电子/半导体 > 可编程逻辑 >

Go切片的内部实现

时间:2023-10-09 | 栏目:可编程逻辑 | 点击:

切片

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 个字段分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量)。

您可能感兴趣的文章:

相关文章