go数据类型-slice底层

发布时间 2023-11-28 20:30:44作者: 杨阳的技术博客

切片的底层数据结构

有上篇string为基础了,能猜到slice肯定也有一个对应的struct。

  在runtime的 slice.go中
     type slice struct {
  	array unsafe.Pointer
  	len   int
  	cap   int
  }

切片的本质是对数组的引用

len 表示当前已经存储的个数,cap表示容量。

切片的创建

  1. 根据数组创建

     s := arr[0:31]
    
  2. 字面量:编译时插入创建数组的代码

     s := []int{1, 2, 3}
    
  3. make:运行时创建数组

     slice := make([lint, 10)
    

切片的追加

扩容时,编译时转为调用 runtime.growslice()
有兴趣的可以看下源码,方法介绍也能看出一些逻辑。

直接小结:

  1.如果期望容量大于当前容量的两倍就会使用期望容量
    
    比如当前是3,期望9,那么即使翻倍也达不到要求,所以直接变成9.      

  2.如果当前切片的长度小于 1024,将容量翻倍
    
    比如当前容量为3, 如果再加一个值,则容量直接变为 6.

  3.如果当前切片的长度大于 1024,每次增加 25%
    

  4.切片扩容时,并发不安全,注意切片并发要加锁,
  
    因为扩容时候,会新创建一个数组,如果在这个过程中,并发访问可能会是访问老的数组。
    因为数组必须是连续的存储空间。