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!
Go 切片的扩容规则是怎么样的的更多相关文章
- Go语言中底层数组和切片的关系以及数组扩容规则
Go语言中底层数组和切片的关系以及数组扩容规则 demo package main import ( "fmt" ) func main() { // 声明一个底层数组,长度为10 ...
- GO语言学习——切片三 append()方法为切片添加元素、切片的扩容策略、使用copy()函数复制切片、从切片中删除元素
append()方法为切片添加元素 注意:通过var声明的零值切片可以在append()函数直接使用,无需初始化. var s []int s = append(s, 1, 2, 3) append( ...
- Go 语言切片是如何扩容的?
原文链接: Go 语言切片是如何扩容的? 在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice). 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装.它非常灵活,支 ...
- Go语言基础之切片
Go语言基础之切片 本文主要介绍Go语言中切片(slice)及它的基本使用. 引子 因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. 例如: func arraySum(x ...
- (7)Go切片
切片 切片(Slice)是一个拥有相同类型元素的可变长度的序列.它是基于数组类型做的一层封装.它非常灵活,支持自动扩容. 切片是一个引用类型,它的内部结构包含地址.长度和容量.切片一般用于快速地操作一 ...
- Go语言 ( 切片)
本文主要介绍Go语言中切片(slice)及它的基本使用. 引子 因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. 例如: func arraySum(x []int) in ...
- 2.4 Go语言基础之切片
本文主要介绍Go语言中切片(slice)及它的基本使用. 一.引子 因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. 例如: func arraySum(x [3]int) ...
- GO学习-(9) Go语言基础之切片
Go语言基础之切片 本文主要介绍Go语言中切片(slice)及它的基本使用. 引子 因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. 例如: func arraySum(x ...
- Go slice 扩容机制分析
前言 我们都知道 Go 语言中的 slice 具有动态扩容的机制(不知道的同学请先补课 Go 切片) 但是其底层机制是什么呢?本着知其然,知其所以然的探索精神去研究一番.还不是为了应试 手动狗头 go ...
- Golang通脉之切片
因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. func arraySum(x [3]int) int{ sum := 0 for _, v := range x{ su ...
随机推荐
- drools 规则引擎和 solon-flow 哪个好? 规则引擎 solon-flow 简明教程
前言 做电子政务的项目时,经常会有大量的业务逻辑变更,但其实里面的业务改动,其实就是一些业务逻辑变动. 而程序员编写的代码也没有任何技术含量,跟着式样书逐字逐句的翻译就行.大量的 if/else 判断 ...
- 认识soui4js(第1篇)
源代码:https://github.com/soui4js/soui4js soui4js是soui4+quickjs的结合体. soui4是一套c++ directui客户端开发框架,soui4j ...
- .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
昨天线上有几个进程因为 StackOverFlowException 导致进程 Crash 了,但是 TCP 请求还是可以连接,具体可不可以连接一个出现StackOverFlowException的微 ...
- Schreier–Sims 算法
好看的实现. #include<bits/stdc++.h> using namespace std; #define int long long const int maxn=105; ...
- Hetao P1156 最大战力 题解 [ 绿 ][ 二分 ][ 最大子段和 ]
最大战力 Vjudge 原题 题解 形式化题意 给定两个数组 \(a[n]\) 和 \(b[n]\) ,需要在数组 \(b\) 中选择一个区间 \(b[l,r]\) ,替换掉区间 \(a[l,r]\) ...
- flutter-超出部分隐藏
第一种写法 1 ConstrainedBox( 2 constraints: BoxConstraints( 3 maxHeight: 100 4 ), 5 child: Stack( 6 overf ...
- 在 WPF 应用程序中缓存应用程序数据
参考学习链接:https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/walkthrough-caching-applicatio ...
- kubesphere应用系列(一)部署NET8API
一.准备工作 1.kubesphere 2.harbor 3.net8 二.创建API应用 1.创建api应用 1.1使用命令创建应用 dotnet new webapi -n YourApiAppN ...
- acwing329 围栏障碍训练场 题解
考试压轴题,意识到这题是线段树优化 \(dp\) 时追悔莫及. 为了简化题目,我将从起点到原点变成了从原点到起点(这样就可以省去两个数组的空间). 想到设 \(dp_{i,j}\) 表示在第 \(i\ ...
- Linux Vim 最全面教程:从入门到精通
一.引言 Vim 是一款功能强大且在 Linux 系统中广泛使用的文本编辑器.它有着高效的编辑模式.丰富的快捷键以及众多强大的功能,对于想要深入学习 Linux 系统操作以及进行文本处理相关工作的新手 ...