Go 切片:用法和本质

news/2025/1/20 15:28:31/

要想更好的了解一个知识点,实战是最好的经历。

题目

我这里放一道题目:

package mainimport "fmt"func SliceRise(s []int) {s = append(s, 0)for i := range s {s[i]++}fmt.Println(s)
}func SlicePrint() {s1 := []int{1, 2}s2 := s1s2 = append(s2, 3)SliceRise(s1)SliceRise(s2)fmt.Println(s1, s2)
}func main() {SlicePrint()
}

大家猜猜本题的运行结果是多少?

s1: 1、2          ||          s2:2、3、4

知识点

是不是蒙了( •̀ ω •́ )✧,蒙了才有效果,才能更加明白自己的不足。

以上涉及了好几个知识点。我一一讲起。

1、切片的底层数据结构

type Slice struct{array   unsafe.Pointer // 储存着数组存放地址len     int            // 切片长度cap     int            // 切片容量
}

切片的底层数据结构是一个 “结构体"

2、切片的扩容机制

slice的扩容遵循以下原则

1、如果slice容量小于1024,则新slice容量扩大为原来的2倍。

2、如果slice容量大于等于1024,采用1.25倍,则新的slice容量将扩大为原来的1.25倍

这里有一点需要注意,当slice扩容时,会开辟一个新的空间,将旧的slice依次复制进入。


学到这里,其实就已经基本OK了,接下来我会放出本题的解析。

解析

大家都知道,切片是引用传递。什么是引用传递呢?就是传递地址值。

但是有一点需要注意,切片的数据结构是结构体,底层是struct。

所以传递时,将会创造一个新的结构体,把老结构体全部粘贴复制进去(地址,len、cap)

s1 := s2

如上,就相当于

相当于把两个结构体,直接复制并拷贝过去复制了一个一模一样的。

显而易见,这两个,是不同的结构体。--> 但是却共同一个共同的地址0111,也就是同一个数组。

到这里大家应该就明白了,他们传递时,传递的是地址。结构体是直接复制过去的一个新的。

s = append(s,0)时,由于新添加了一个值,导致容量扩大,cap增加。这时就会分配一个新地址给s结构体。而原来的s1结构体内,存的地址不会改变。

故fmt.Println(s1)是:1、2。

而s2,用同样的分析,亦可得出结论。


http://www.ppmy.cn/news/1564683.html

相关文章

搜维尔科技提供完整的人形机器人解决方案以及训练系统

问题:从灵巧手收集的数据是否也会在大脑大模型中训练,或是在专门用于手部控制的单独模型中训练? Q: If the data collected from dexterous hands will be trained as well in the brain large model, or in a separate model dedicated for…

mysql 系统学习1

Linux C/C 操作MySQL - Henkk - 博客园

基于SSM的家庭记账本小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

云原生前端开发:打造现代化高性能的用户体验

引言:前端开发的新风向 在过去的几年中,前端开发领域经历了快速的演变,从早期的静态网页到如今复杂的单页应用(SPA),再到微前端架构和渐进式Web应用(PWA),前端技术一直处…

用 Python 从零开始创建神经网络(二十二):预测(Prediction)/推理(Inference)(完结)

预测(Prediction)/推理(Inference)(完结) 引言完整代码: 引言 虽然我们经常将大部分时间花在训练和测试模型上,但我们这样做的核心原因是希望有一个能够接受新输入并生成期望输出的…

使用 Parcel 和 NPM 脚本进行打包

使用 Parcel 和 NPM 脚本进行打包 Parcel Parcel 是一个零配置的网页应用程序打包工具,主要用于快速构建现代 JavaScript 应用。 我们可以使用npm直接安装它 npm install --save-dev parcel //这将把 Parcel 添加到 devDependencies 中,表明它是一个…

【Sanic 框架 / 1】深入学习:从入门到进阶

文章目录 一、基础知识学习(入门)Sanic 简介什么是 Sanic 框架?Sanic 的优势和适用场景1. 高性能2. 异步支持3. 简洁易用4. WebSocket 支持5. 灵活扩展 环境搭建1. 安装 Python(3.7 及以上版本)2. 创建虚拟环境3. 安装…

Java调用C/C++那些事(JNI)

一、引言 Java开发中,可能会遇到一些需要复用、移植C/C库的场景。 比如说,对于某些特定功能,C/C已有代码实现,但是Java没有。为了可以让Java成功使用该功能,有几种方式: 优势劣势将C/C代码翻译成Java代码…