Golang 切片slice源码走读

切片slice是golang中非常经典的数据结构,其定位可以类比其他语言中的动态数组。 切片中的元素存放在一块内存地址连续的区域,使用索引可以快速检索到指定位置的元素;切片长度和容量是可变的,在使用过程中可以根据需要进行扩容。
本文对应的Golang版本是1.21.9

数据结构

// src/runtime/slice.go
type slice struct {
   
    array unsafe.Pointer
    len int
    cap int
}

array 指针指向底层数组, len表示切片长度,cap表示底层数组容量。

初始化

声明和初始化主要通过 1) 变量声明 2) 字面量 3) 使用内置函数make() 4) 从切片和数组中切取

func makeslice(et *_type, len, cap int) unsafe.Pointer {
   
	mem, overflow := math.MulUintptr(et.Size_, uintptr(cap))
	if overflow || mem > maxAlloc || len < 0 || len > cap {
   
		mem, overflow := math.MulUintptr(et.Size_, uintptr(len))
		if overflow || mem > maxAlloc || len < 0 {
   
			panicmakeslicelen()
		}
		panicmakeslicecap()
	}

	return mallocgc(mem, et, true)
}
  1. 调用 math.MulUintptr 的方法,结合每个元素的大小以及切片的容量,计算出初始化切片所需要的内存空间大小。
  2. 如果容量超限,len 取负值或者 len 超过 cap,直接 panic
  3. 调用位于 runtime/malloc.go 文件中的 mallocgc 方法,为切片进行内存空间的分配

元素追加

a := []int{
   1,2,3,4,5}
b := a[1:4]
b = append(b, 10) // 此时元素a[4]将由5变成0

此时需要借助扩展表达式 (完整切片表达式)
a := []int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值