Go语言中切片的len和cap的关系

Go语言中,切片类型是包含三个属性:1.地址(暂且不在本次讨论范围内) 2.长度 3.容量

一.概念说明

  1. 长度:切片中实际存在元素的数量
  2. 容量:从切片的起始元素开始到其底层数组中最后一个元素的数量

二.切片生成方式

  1. 从数组生成一个新的切片
  2. 从切片生成一个新的切片
  3. 直接生成一个新的切片
1.从数组生成一个新的切片

测试代码:

package my_test

import "testing"

func TestSliceLenCap(t *testing.T) {
	var arr = [5]int{1, 22, 333, 444, 5555}
	var s1 = arr[1:3]
	t.Log(len(s1), cap(s1))
}

简单分析:
首先简单分析猜测一下切片s1的lencap,根据lencap的概念说明:len是切片中实际的元素个数,s1是arr截取的,arr[1:3],idx[1]取到,idx[3]取不到,也就是[22,333],所以len是2;cap是切片起始元素到底层数组最后一个元素,起始元素是22,对应的idx是1,数组arr最后一个元素是5555,对应的idx是4,也就是1-4,总共是4个元素,所以cap是4

结果验证:
=== RUN TestSliceLenCap
my_test.go:8: [22 333]
my_test.go:9: 2 4
— PASS: TestSliceLenCap (0.00s)
PASS
ok command-line-arguments 0.104s

2.从切片生成一个新的切片

其实和从数组生成一个新的切片效果是类似的,我们直接上测试结果:

测试代码:

package my_test

import "testing"

func TestSliceLenCap(t *testing.T) {
	var arr = [5]int{1, 22, 333, 444, 5555}
	var s1 = arr[1:3]
	var s2 = s1[0:1]
	t.Log(s1)
	t.Log(len(s1), cap(s1))
	t.Log(s2, len(s2), cap(s2))
}

验证结果:
=== RUN TestSliceLenCap
my_test.go:9: [22 333]
my_test.go:10: 2 4
my_test.go:11: [22] 1 4
— PASS: TestSliceLenCap (0.00s)
PASS
ok command-line-arguments 0.083s

整个分析过程与结果与之前的一致。

3.直接声明一个新切片

测试代码

package my_test

import "testing"

func TestSliceLenCap(t *testing.T) {
	var s10 = []int{1, 2, 3, 4, 5}   //申明的同时初始化
	t.Log(s10, len(s10), cap(s10))

	s20 := make([]int, 2, 4) 			//通过make申明
	t.Log(s20, len(s20), cap(s20))
}

验证结果:
=== RUN TestSliceLenCap
my_test.go:7: [1 2 3 4 5] 5 5
my_test.go:10: [0 0] 2 4
— PASS: TestSliceLenCap (0.00s)
PASS
ok command-line-arguments 0.104s

三.增删切片对len和cap的影响

测试代码

package my_test

import "testing"

func TestSliceLenCap(t *testing.T) {
	s20 := make([]int, 2, 4) //通过make申明
	t.Log(s20, len(s20), cap(s20))
	s20 = append(s20, 1, 2, 3)
	t.Log(s20, len(s20), cap(s20))

	s30 := make([]int, 2, 4)
	for i := 0; i < 10; i++ {
		s30 = append(s30, i)
		t.Log(s30, len(s30), cap(s30))
	}
}

验证结果:
=== RUN TestSliceLenCap
my_test.go:7: [0 0] 2 4
my_test.go:9: [0 0 1 2 3] 5 8
my_test.go:14: [0 0 0] 3 4
my_test.go:14: [0 0 0 1] 4 4
my_test.go:14: [0 0 0 1 2] 5 8
my_test.go:14: [0 0 0 1 2 3] 6 8
my_test.go:14: [0 0 0 1 2 3 4] 7 8
my_test.go:14: [0 0 0 1 2 3 4 5] 8 8
my_test.go:14: [0 0 0 1 2 3 4 5 6] 9 16
my_test.go:14: [0 0 0 1 2 3 4 5 6 7] 10 16
my_test.go:14: [0 0 0 1 2 3 4 5 6 7 8] 11 16
my_test.go:14: [0 0 0 1 2 3 4 5 6 7 8 9] 12 16
— PASS: TestSliceLenCap (0.00s)
PASS
ok command-line-arguments 0.054s

结果分析:
初始cap是4,len是2(初始为零值0),append3个元素之后,即变成5个元素,但是此时len超过cap了,Go语言中cap小于len之后,cap会双倍扩容,这边就是由原来的4->8

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值