go语言slice详解|青训营笔记

130 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

go slice 详解

slice是类似动态数组的一种数据结构,依托数组实现。

type slice struct{
    array unsafe.Pointer
    len int
    cap int
}
  • array指针指向底层数组
  • len表示切片长度
  • cap表示底层数组容量

使用make创建Slice

  • 使用make来创建Slice时,可以同时指定长度和容量
  • 创建时底层会分配一个数组,数组的长度即容量

Slice扩容

  • 使用append向Slice追加元素时,如果Slice空间不足,将会触发Slice扩容
  • 扩容实际上重新一配一块更大的内存
  • 将原Slice数据拷贝进新Slice
  • 然后返回新Slice
  • 扩容后再将数据追加进去

扩容机制

  • 当数组容量小于1024时,每次扩容一倍
  • 当数组容量大于等于1024时,每次扩容约0.25倍,也就是扩容约四分之一的容量 为什么是约呢 这里涉及到内存对齐

slice的追加

使用append向Slice追加元素时, 如果Slice空间不足, 将会触发Slice扩容, 扩容实际上重新一配一块更大的内存, 将原Slice数据拷贝进新Slice, 然后返回新Slice, 扩容后再将数据追加进去。 扩容容量的选择遵循以下规则: 如果原Slice容量小于1024, 则新Slice容量将扩大为原来的2倍; 如果原Slice容量大于等于1024, 则新Slice容量将扩大为原来的1.25倍;

slice的拷贝

使用copy()内置函数拷贝两个切片,但是需要注意的是,copy 会将源切片的数据逐个拷贝到目的切片指向的数组中, 拷贝数量取两个切片长度的最小值。copy不会扩容,只有append才会扩容。 基于以上切片特性。编程过程需要注意: 1.创建切片时可跟据实际需要预分配容量, 尽量避免追加过程中扩容操作, 有利于提升性能; 2.切片拷贝时需要判断实际拷贝的元素个数 3.谨慎使用多个切片操作同一个数组, 以防读写冲突