当前位置: 首页 > article >正文

Go 切片的扩容规则是怎么样的

切片是动态数组,容量是根据元素动态增加的。

本来想看看源码怎么写的,发现切片追加元素的方法是内置的,看起来还挺麻烦

源码位于 builtin.go 中:

// The append built-in function appends elements to the end of a slice. If  
// it has sufficient capacity, the destination is resliced to accommodate the  
// new elements. If it does not, a new underlying array will be allocated.  
// Append returns the updated slice. It is therefore necessary to store the  
// result of append, often in the variable holding the slice itself:  
//  
//  slice = append(slice, elem1, elem2)  
//  slice = append(slice, anotherSlice...)  
//  
// As a special case, it is legal to append a string to a byte slice, like this:  
//  
//  slice = append([]byte("hello "), "world"...)  
func append(slice []Type, elems ...Type) []Type

那么,就用简单的方法来推算规则。编写下面的单测代码,循环 100 次,每次追加 1个元素,看看切片的长度和容量的变化规律是什么。

func TestSliceAppend(t *testing.T) {  
    slice := make([]int, 0)  
    t.Logf("len:%d cap:%d slice:%v", len(slice), cap(slice), slice)  
    for i := 0; i < 100; i++ {  
       slice = append(slice, i)  
       t.Logf("len:%d cap:%d slice:%v", len(slice), cap(slice), slice)  
    }  
}

输出结果:

slice_test.go:54: len:0 cap:0 slice:[]
slice_test.go:57: len:1 cap:1 slice:[0]
slice_test.go:57: len:2 cap:2 slice:[0 1]
slice_test.go:57: len:3 cap:4 slice:[0 1 2]
slice_test.go:57: len:4 cap:4 slice:[0 1 2 3]
slice_test.go:57: len:5 cap:8 slice:[0 1 2 3 4]
slice_test.go:57: len:6 cap:8 slice:[0 1 2 3 4 5]
slice_test.go:57: len:7 cap:8 slice:[0 1 2 3 4 5 6]
slice_test.go:57: len:8 cap:8 slice:[0 1 2 3 4 5 6 7]
slice_test.go:57: len:9 cap:16 slice:[0 1 2 3 4 5 6 7 8]
slice_test.go:57: len:10 cap:16 slice:[0 1 2 3 4 5 6 7 8 9]
slice_test.go:57: len:11 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10]
slice_test.go:57: len:12 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10 11]
slice_test.go:57: len:13 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12]
slice_test.go:57: len:14 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13]
slice_test.go:57: len:15 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
slice_test.go:57: len:16 cap:16 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
slice_test.go:57: len:17 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
slice_test.go:57: len:18 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
slice_test.go:57: len:19 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]
slice_test.go:57: len:20 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
slice_test.go:57: len:21 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
slice_test.go:57: len:22 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21]
slice_test.go:57: len:23 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22]
slice_test.go:57: len:24 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
slice_test.go:57: len:25 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
slice_test.go:57: len:26 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
slice_test.go:57: len:27 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]
slice_test.go:57: len:28 cap:32 slice:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27]
...

这里没有都粘贴过来,容量的规则是每次是原来的 2 倍。

Over!


http://www.kler.cn/news/361071.html

相关文章:

  • 【数据库】T SQL语句和SSMS有啥联系?
  • 学习鸿蒙Next 之路 http
  • JAVA继承和多态
  • 18.VScode写Java项目的教程
  • 使用ETL进行数据接入的方式
  • 深入探索LINUX中AWK命令:强大的文本处理工具
  • 后端常用安全措施
  • idea中,git提交时忽略某些本地修改.将文件从git暂存区移除
  • 使用GraphRAG系统实现本地部署的Ollama模型问答系统
  • 实现鼠标经过某个元素时弹出提示框(通常称为“工具提示”或“悬浮提示”)
  • 虚拟培训引领潮流:首个电力调度元宇宙标准获批立项
  • 大数据干了什么?
  • 【D3.js in Action 3 精译_035】4.1 D3 中的坐标轴的创建(下篇):坐标轴与轴标签的具体实现
  • 【Go进阶】协程的创建以及通信
  • 我是类(最终版)
  • Java | Leetcode Java题解之第491题非递减子序列
  • 在windows上开发的python程序能直接在linux上跑吗?
  • echarts柱状图数据太多,如何实现鼠标滑动查看
  • 【五】企业级JavaScript开发之入门
  • Android 原生程序使用gdb, addr2line, readelf调试