【golang探索计划】golang slice 分片的探讨与总结

开头

来个简单的开头,今天认真学习一下golang基本结构Slice,不然这个总结我总是没办法写出来,真的是万事开头难!!!

定义与基本使用

不知道从那个地方开始,先看看slice的基本结构

type slice struct {
	array unsafe.Pointer // 数组指针
	len   int //数组元素个数
	cap   int // 可以容纳的个数
}

示意图(源自)如下所示
Slice示意图

简单说一下这里len和cap的区别,定义里说len是元素的个数,其实也代表授权使用的空间,简单来说可以直接用下标去更改对应的值,但是len到cap的空间是不能直接访问的,可理解为未授权; cap个人理解是已经向操作系统分配了空间但你目前只能够访问到的长度是len,其次也是作为扩容的标志,下一次空间扩容是按照cap的2倍(当大于 1024时 ,1.25 倍)大小向操作系统进行申请空间。下面具体示例看看

  1. 初始化一个slice
var testSlice []int // 定义的一个空的slice,数组指针为nil,len和cap为0
s := new([]int) //这里返回的是slice结构体的指针,所以使用是需要加*,如*s[...],或者append(*s, ...)
testSlice1 := make([]int, 5) // len=cap=5,数组元素都为0
testSlice2 := make([]int, 0, 5) // len=0,cap=5,
testSlice3 := make([]int, 1, 5) // len=1,cap=5,有一个数组元素为0
  1. 添加元素
testSlice = append(testSlice, 1) // 这里可以用append,但不能直接testSlice[0]=1,因为没有分配空间,经过append,len=cap=1
testSlice = append(testSlice, 1) //len=cap=2
testSlice = append(testSlice, 1) //len3, cap=4

testSlice1[0] = 1
testSlice1[1] = 2
testSlice1[2] = 3
testSlice1[3] = 4
testSlice1[4] = 5
testSlice1[5] = 6 //panic, 超出了授权分配空间 index out of range [5] with length 5
testSlice1 = append(testSlice1, 6)// 这里一定要将返回的结果复制给旧的,不然append操作对旧的不生效

这里简单介绍一下扩容的步骤,详细可以去阅读一下源码在runtime/slice.go。首先根据先前计算的 cap,申请新的内存空间,这里是全量申请,不是差额申请;然后 然就将旧的上的 所有元素拷贝到新的内存空间上,然后生成一个新的slice对象,并更新cap值和数组指针,最后返回。所以一般建议初始化slice时优先进行预分配,也就是用make告诉编译器你需要存多少个元素,一次申请,不用每次append频繁的取申请内存空间。

  1. 分片
testSlice4 := testSlice1[1:3]
print(testSlice1, testSlice4) // [5/5]0xc0000b2030[2/4]0xc0000b2038 [1 2 3 4 5] [2 3]
testSlice4 =append(testSlice4, 6)
testSlice4 =append(testSlice4, 6) // [5/5]0xc0000b2030[4/4]0xc0000b2038
testSlice4 =append(testSlice4, 6) // [5/5]0xc0000b2030 [5/8]0xc0000c0000 [1 2 3 6 6] [2 3 6 6 6]

特点:

  1. 在分片对象testSlice4 发生扩容之前,一直和原生对象testSlice1共用一块内存空间,只是起始地址存在偏移量差别
  2. 在分片对象testSlice4 发生扩容之前,向testSlice4 append数据会覆盖原生的testSlice1,示意图如下
    在这里插入图片描述
    ==================================================================
    后续再补充…
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值