千家信息网

slice是如何扩容的

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容介绍了"slice是如何扩容的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题1,slic
千家信息网最后更新 2026年11月01日slice是如何扩容的

本篇内容介绍了"slice是如何扩容的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

问题1,slice的底层数据结构

我擦,这么直接的嘛?

我猜是数组加链表,结果猜错了0分。

翻看源码。

runtime/slice.go

type slice struct {        array unsafe.Pointer  //数据结构是简单粗暴的数组指针        len   int        cap   int}

问题2,slice是如何扩容的

又猜错了~

还是继续看源码吧

从源码找了半天,发现一个这。

growslice handles slice growth during append.

so,就是你了。

func growslice(et *_type, old slice, cap int) slice { // 第三个cap,新的最小容量        //巴拉巴拉巴拉 一堆判断        newcap := old.cap  //变量存储空间大小        doublecap := newcap + newcap  //双倍空间大小        if cap > doublecap {  //如果历史空间大于双倍的容量,新的最小容量                newcap = cap        } else {                //如果长度小于 1024  新长度就是2倍老容量                if old.len < 1024 {                        newcap = doublecap                } else {                        //当大于1024 走公式   newcap += newcap / 4,直到newcap大于等于老cap                        for 0 < newcap && newcap < cap {                                newcap += newcap / 4                        }                        if newcap <= 0 {                                newcap = cap                        }                }        }        var overflow bool        var lenmem, newlenmem, capmem uintptr        //对et的size做匹配,获取需要申请的空间大小        //1 不处理直接分配        //系统指针大小 进行计算和位运算        //2 唯一运算        //默认 相乘        switch {        case et.size == 1:                lenmem = uintptr(old.len)                newlenmem = uintptr(cap)                capmem = roundupsize(uintptr(newcap))                overflow = uintptr(newcap) > maxAlloc                newcap = int(capmem)        case et.size == sys.PtrSize:                lenmem = uintptr(old.len) * sys.PtrSize                newlenmem = uintptr(cap) * sys.PtrSize                capmem = roundupsize(uintptr(newcap) * sys.PtrSize)                overflow = uintptr(newcap) > maxAlloc/sys.PtrSize                newcap = int(capmem / sys.PtrSize)        case isPowerOfTwo(et.size):                var shift uintptr                if sys.PtrSize == 8 {                        // Mask shift for better code generation.                        shift = uintptr(sys.Ctz64(uint64(et.size))) & 63                } else {                        shift = uintptr(sys.Ctz32(uint32(et.size))) & 31                }                lenmem = uintptr(old.len) << shift                newlenmem = uintptr(cap) << shift                capmem = roundupsize(uintptr(newcap) << shift)                overflow = uintptr(newcap) > (maxAlloc >> shift)                newcap = int(capmem >> shift)        default:                lenmem = uintptr(old.len) * et.size                newlenmem = uintptr(cap) * et.size                capmem, overflow = math.MulUintptr(et.size, uintptr(newcap))                capmem = roundupsize(capmem)                newcap = int(capmem / et.size)        }        //如果append一次超过过多的元素新增,直接报错,越界,超出容量大小        if overflow || capmem > maxAlloc {                panic(errorString("growslice: cap out of range"))        }        var p unsafe.Pointer //申请新的内存,并把指针指向p        if et.ptrdata == 0 {                p = mallocgc(capmem, nil, false)                memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)        } else {                p = mallocgc(capmem, et, true)                if lenmem > 0 && writeBarrier.enabled {                        bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem)                }        }        //将老的数据移动到新的数据        memmove(p, old.array, lenmem)        return slice{p, old.len, newcap}}

总结

其实可以看出,golang的切片扩容是比较粗暴的,直接赋值拷贝。不过,golang区分的长度和容量两种单位计量,一般会提前分配足够的cap,可以减少maclloc的次数。

"slice是如何扩容的"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

容量 数据 大小 源码 空间 长度 最小 粗暴 内容 双倍 就是 指针 数据结构 数组 更多 知识 结构 问题 巴拉 实用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司排名 A股互联网金融科技公司 银优互联网科技有限公司 美国互联网黑科技 易通互联网络科技有限公司 互联网金融 科技创新 银川新华互联网科技学校地址 互联网和高科技公司 云创客互联网科技公司 温州喔噻互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 科技与互联网哪个更好 华服互联网科技官网 互联网软件和科技 爱医互联网络科技 怎样加入科技互联网 互联网相关科技技术 陕西九四连强互联网科技有限公司 华人运通互联网科技公司 黑龙江互联网科技公司 互联网科技工作委员会 北京互联网络科技有限公司 字节跳动和互联网科技 互联网科技有哪些公司 996高科技互联网公司 河南住房之家互联网科技 中国互联网公司排名锤子科技 南博望互联网科技有限公司 伍佰万互联网科技怎么赚钱 深圳无忧互联网科技
0