go语言基础|slice入门

news2025/7/28 0:32:56

slice

slice介绍

slice中文叫切片,是go官方提供的一个可变数组,是一个轻量级的数据结构,功能上和c++的vector,Java的ArrayList差不多。

slice和数组是有一些区别的,是为了弥补数组的一些不足而诞生的数据结构。最大的区别就是数组长度固定,不可扩容,而切片是可以扩容的。也就是这个功能的区别导致了后续一系列的区别,例如在传参上面,数组是整个数组的值复制过去传到函数里,而切片则是传递指针等。

 func change(arr *[3]int) {
     arr[0] = 1
 }
 func change1(arr [3]int) {
     arr[0] = 1
 }
 func TestName(t *testing.T) {
     arr := [3]int{1, 2, 3}
     arr[0] = 2
     change(&arr)
     //change1(arr) // 这两者的结果是不一样的
     fmt.Println(arr[0])
 }

那么slice是什么呢? slice结构体源码如下:(在runtime/slice.go中)

 type slice struct {
     array unsafe.Pointer // 指向底层数组的指针
     len   int            // 当前长度
     cap   int            // 总容量
 }

slice扩容机制

1.18之前的方式和现在不太一样,Go1.18之前切片的扩容是以容量1024为临界点,当旧容量 < 1024个元素,扩容变成2倍;当旧容量 > 1024个元素,那么会进入一个循环,每次增加25%直到大于期望容量。

 func TestSliceGrowing(t *testing.T) {
    s := []int{}
    for i := 0; i < 4098; i++ {
       s = append(s, i)
       t.Log(len(s), cap(s))
    }
 }
 ​
 作者:starine
 链接:https://juejin.cn/post/7101928883280150558
 来源:稀土掘金
 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Go1.18不再以1024为临界点,而是设定了一个值为256的threshold,以256为临界点;超过256,不再是每次扩容1/4,而是每次增加(旧容量+3*256)/4;

当新切片需要的容量大于两倍的旧容量时,则直接按照新切片需要的容量扩容; else: 当原 slice 容量 < threshold 的时候,新 slice 容量变成原来的 2 倍; 当原 slice 容量 > threshold,进入一个循环,每次容量增加(旧容量+3*threshold)/4。

作者:starine 链接:https://juejin.cn/post/7101928883280150558 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 func growslice(et *_type, old slice, cap int) slice {
    //  ......
     newcap := old.cap
     doublecap := newcap + newcap    //双倍扩容(原容量的两倍)
     if cap > doublecap {   //如果所需容量大于 两倍扩容,则直接扩容到所需容量
         newcap = cap
     } else {
         const threshold = 256   //这里设置了一个 阈值 -- 256
         if old.cap < threshold {        //如果旧容量 小于 256,则两倍扩容
             newcap = doublecap   
         } else {
         // 检查 0 < newcap 以检测溢出并防止无限循环。
             for 0 < newcap && newcap < cap {   //如果新容量 > 0  并且 原容量 小于 所需容量
         
                // 从小片的增长2x过渡到大片的增长1.25x。这个公式给出了两者之间的平滑过渡。(这里的系数会随着容量的大小发生变化,从2.0到无线接近1.25)
                 newcap += (newcap + 3*threshold) / 4
               
                 
               //当newcap计算溢出时,将newcap设置为请求的上限。
             if newcap <= 0 {   // 如果发生了溢出,将新容量设置为请求的容量大小
                 newcap = cap
             }
         }
     }
 }

具体情况如下:

如果请求容量 大于 两倍现有容量 ,则新容量 直接为请求容量
 否则(请求容量 小于等于 两倍现有容量) 如果 现有容量 小于 256 ,则新容量是原来的两倍
 否则:新容量 = 1.25 原容量 + 3/4 阈值

golang slice (切片) 扩容机制详解(1.18版本后) - 小星code - 博客园

这么设计的目的是为了扩容能平滑,更好地节省内存。

传参问题

slice被make出来就是一个结构体的实例。当作为一个参数传递到方法里,会传递一个这个slice实例的值过去,这也是导致slice传参会有一些列奇怪现象的原因(可以修改值但无法扩容等)。可以修改数值的原因是这个值中的array指针是指向原数组的,但是无法扩容的原因是修改这个值的指针对原slice是无影响的;而传递slice指针可以修改成功是因为本质是就是在修改原方法层面的slice,而不是修改传递后slice的值。

线程安全性问题

slice是线程不安全的数据结构,因此会存在竞态条件(race condition),处理原则要么只读,要么加锁

Slice 的底层是 数组指针 + len + cap,这几个在并发时候都可能出现竞态条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 HTML + JavaScript 实现可拖拽的任务看板系统

本文将介绍如何使用 HTML、CSS 和 JavaScript 创建一个交互式任务看板系统。该系统支持拖拽任务、添加新任务以及动态创建列,适用于任务管理和团队协作场景。 效果演示 页面结构 HTML 部分主要包含三个默认的任务列(待办、进行中、已完成)和一个用于添加新列的按钮。 <…

统信 UOS 服务器版离线部署 DeepSeek 攻略

日前&#xff0c;DeepSeek 系列模型因拥有“更低的成本、更强的性能、更好的体验”三大核心优势&#xff0c;在全球范围内备受瞩目。 本次&#xff0c;我们为大家提供了在统信 UOS 服务器版 V20&#xff08;AMD64 或 ARM64 架构&#xff09;上本地离线部署 DeepSeek-R1 模型的…

美尔斯通携手北京康复辅具技术中心开展公益活动,科技赋能助力银龄健康管理

2025 年 5 月 30 日&#xff0c;北京美尔斯通科技发展股份有限公司携手北京市康复辅具技术中心&#xff0c;在朝阳区核桃园社区开展 “全国助残日公益服务” 系列活动。活动通过科普讲座、健康检测与科技体验&#xff0c;将听力保健与心脏健康服务送至居民家门口&#xff0c;助…

Redis Stack常见拓展

Redis JSON RedisJSON 是 Redis Stack 提供的模块之一&#xff0c;允许你以 原生 JSON 格式 存储、检索和修改数据。相比传统 Redis Hash&#xff0c;它更适合结构化文档型数据&#xff0c;并支持嵌套结构、高效查询和部分更新。 #设置⼀个JSON数据,其中$表示JSON数据的根节点…

Linux 驱动之设备树

Linux 驱动之设备树 参考视频地址 【北京迅为】嵌入式学习之Linux驱动&#xff08;第七期_设备树_全新升级&#xff09;_基于RK3568_哔哩哔哩_bilibili 本章总领 1.设备树基本知识 什么是设备树&#xff1f; ​ Linux之父Linus Torvalds在2011年3月17日的ARM Linux邮件列表…

12、企业应收账款(AR)全流程解析:从发票开具到回款完成

在商业活动中&#xff0c;现金流如同企业的命脉&#xff0c;而应收管理则是维系这条命脉正常运转的重要保障。许多企业由于对应收账款缺乏有效管理&#xff0c;常常面临资金周转困难的问题。实践证明&#xff0c;建立科学的应收管理体系能够显著提升资金回笼效率&#xff0c;为…

【notepad++】如何设置notepad++背景颜色?

如何设置notepad背景颜色&#xff1f; 设置--语言格式设置 勾选使用全局背景色 例如选择护眼色---80&#xff0c;97&#xff0c;205&#xff1b;

使用 C++/OpenCV 制作跳动的爱心动画

使用 C/OpenCV 制作跳动的爱心动画 本文将引导你如何使用 C 和 OpenCV 库创建一个简单但有趣的跳动爱心动画。我们将通过绘制参数方程定义的爱心形状&#xff0c;并利用正弦函数来模拟心跳的缩放效果。 目录 简介先决条件核心概念 参数方程绘制爱心动画循环模拟心跳效果 代码…

在Oxygen编辑器中使用DeepSeek

罗马尼亚公司研制开发的Oxygen编辑器怎样与国产大模型结合&#xff0c;这是今年我在tcworld大会上给大家的分享&#xff0c;需要ppt的朋友请私信联系 - 1 - Oxygen编辑器中的人工智能助手 Oxygen编辑器是罗马尼亚的Syncro Soft公司开发的一款结构化文档编辑器。 它是用来编写…

一、基础环境配置

一、虚拟机 主&#xff1a;192.168.200.200 从&#xff1a;192.168.200.201 从&#xff1a;192.168.200.202 二、docker docker基础搭建&#xff0c;有不会的自行百度。 1.目录结构 /opt/software&#xff1a;软件包/opt/module&#xff1a;解压包&#xff0c;自定义脚本…

论文阅读笔记——FLOW MATCHING FOR GENERATIVE MODELING

Flow Matching 论文 扩散模型&#xff1a;根据中心极限定理&#xff0c;对原始图像不断加高斯噪声&#xff0c;最终将原始信号破坏为近似的标准正态分布。这其中每一步都构造为条件高斯分布&#xff0c;形成离散的马尔科夫链。再通过逐步去噪得到原始图像。 Flow matching 采取…

SQL Views(视图)

目录 Views Declaring Views Example: View Definition Example: Accessing a View Advantages of Views Triggers on Views Interpreting a View Insertion&#xff08;视图插入操作的解释&#xff09; The Trigger Views A view is a relation defined in terms of…

「卫星百科」“绿色守卫”高分六号

高分六号&#xff08;GF-6&#xff09;是中国高分辨率对地观测系统&#xff08;高分专项&#xff09;的重要组成卫星&#xff0c;于2018年6月2日成功发射。高分六号卫星凭借其高时空分辨率、红边波段、宽覆盖能力&#xff0c;在农业、生态、灾害等领域提供了重要的数据支撑。本…

秋招Day12 - 计算机网络 - IP

IP协议的定义和作用&#xff1f; IP协议用于在计算机网络中传递数据包&#xff0c;定义了数据包的格式和处理规则&#xff0c;确保数据能够从一个设备传递到另一个设备&#xff0c;中间可能经过多个不同的设备&#xff08;路由器&#xff09;。 IP协议有哪些作用&#xff1f;…

【前端】CSS面试八股

网上现有资料已经很丰富了&#xff0c;我挑了些自己押面试题时总结过的来写。 Q&#xff1a;回流和重绘 A&#xff1a; 回流reflow&#xff1a;计算元素的几何&#xff0c;引发layout重绘repaint&#xff1a;更新元素可见样式&#xff0c;引发paint 回流的成本比重绘高得多&…

Redis底层数据结构之字典(Dict)

Dict基本结构 Dict我们可以想象成目录&#xff0c;要翻看什么内容&#xff0c;直接通过目录能找到页数&#xff0c;翻过去看。如果没有目录&#xff0c;我们需要一页一页往后翻&#xff0c;这样时间复杂度就与遍历的O(n)一样了&#xff0c;而用了Dict我们就可以在O(1)的时间复杂…

佰力博科技与您探讨低温介电温谱测试仪的应用领域

低温介电温谱测试应用领域有如下&#xff1a; 一、电子材料&#xff1a; 低温介电温谱测试仪广泛应用于电子材料的性能测试&#xff0c;如陶瓷材料、半导体材料、压电材料等。通过该设备&#xff0c;可以评估材料在高温或低温环境下的介电性能&#xff0c;为材料的优化和应用提…

【办公类-48-04】202506每月电子屏台账汇总成docx-5(问卷星下载5月范围内容,自动获取excel文件名,并转移处理)

背景需求&#xff1a; 1-4月电子屏表格&#xff0c;都是用这个代码将EXCEL数据整理成分类成3个WORD表格。 【办公类-48-04】20250118每月电子屏台账汇总成docx-4&#xff08;提取EXCLE里面1月份的内容&#xff0c;自制月份文件夹&#xff09;-CSDN博客文章浏览阅读1.2k次&…

基于 ZYNQ UltraScale+ OV5640的高速图像传输系统设计,支持国产替代

引 言 随着电子信息技术的不断进步&#xff0c;人工智能、医 疗器械、机器视觉等领域都在高速发展 [1] &#xff0c;工业相机 是机器视觉系统中的一部分 [2] &#xff0c;对工业相机而言&#xff0c;传 输图像的速率、传输过程的抗干扰能力是其关键&#xff0c; 工业相…

demo_win10配置WSL、DockerDesktop环境,本地部署Dify,ngrok公网测试

win10配置WSL、DockerDesktop环境&#xff0c;本地部署Dify&#xff0c;ngrok分享测试 一、配置WSL 1.1 开启Hyper-V 安装WSL2首先要保证操作系统可以开启hyper-v功能&#xff0c;默认支持开启hyper-v的版本为&#xff1a;Windows11企业版、专业版或教育版,而家庭版是不支持…