你以为传切片就是传引用了吗?

news2024/11/19 15:35:05

xdm ,我们在写 golang 的时候,引用和传值傻傻分不清,就例如我们传 切片 的时候,你能分清楚你传的切片是传值还是传引用呢?

引用是什么?

引用就是给对象起另一个名字,引用类型引用另一种类型

引用并不是对象,相反的,它只是为一个已存在的对象所起的另外一个名字

我们在写 C++ 的时候,知道引用其实就是实际值的另外一个别名,有的会举例子说是一个门牌号的概念

你以为的 引用传递

写个例子,咱们创建一个 切片 s1,

  • s1 切片赋值 , 1, 2, 3, 4, 5 , 输出效果
  • 将 s1 传递给 myModify ,在函数中修改 第 3 个元素第 4 个元素的值
func main() {

	s1 := make([]int, 5)
	s1 = []int{ 1, 2, 3, 4, 5}
	fmt.Println("s1 = ", s1)
	myModify(s1)
	fmt.Println("myAdd result = ", s1)

}

func myModify(ss []int ) {
	ss[2] = 8
	ss[3] = 9
}

查看效果

# go run main.go
s1 =  [1 2 3 4 5]
myAdd result =  [1 2 8 9 5]

看到这里,你以为的引用传递是不是就是这个样子的,因为传入到函数中的切片,在函数中把传进来的切片的值修改,外面实际的切片对应的值也改变了

xdm , 看到这里你就下定论是不是不太好,咱们再来探究一下

确认还是引用吗?

咱们在上面的实现上面具体的打印出 切片的地址来看看效果,我们就稍微有点感觉了

func main() {

	s1 := make([]int, 5)
	s1 = []int{ 1, 2, 3, 4, 5}
	fmt.Printf("s1地址  =  %p , s1: %v \r\n",&s1, s1)
	myModify(s1)
	fmt.Printf("s1地址  =  %p , s1: %v \r\n",&s1, s1)

}

func myModify(ss []int ) {

	ss[2] = 8
	ss[3] = 9
	fmt.Printf("ss地址  =  %p , s1: %v \r\n",&ss, ss)
}

运行程序,看实际效果

# go run main.go
s1地址  =  0xc42000a060 , s1: [1 2 3 4 5]
ss地址  =  0xc42000a0a0 , s1: [1 2 8 9 5]
s1地址  =  0xc42000a060 , s1: [1 2 8 9 5]

这个时候,你还觉得咱们传递的是引用吗?这个做法还是引用传递吗?咱们要好好思考一下

s1切片的地址 是 0xc42000a060 ,ss 切片的地址是 0xc42000a0a0,这里很明显看出来 s1 和 ss 并不是同一个东西,因此,我们可以得出结论,切片作为函数参数,是值传递

可以为什么 s1 和 ss 打印出来的数据是一样的呢,而且修改了 ss 切片里面的元素为什么会影响到原来 s1 的切片呢?

开始探究

GO 里面的切面的底层是是一个结构体

type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}

对于上面的问题, s1 和 ss 变量,有各自变量的内存地址,但是这个变量下面对应的底层数组是对应的同一片空间,因此 s1 的变动会影响到 ss 切片的变动

对于这个我们也是很好验证的,来写一个例子,将上述的两个切片里面的每隔元素的地址都打印出来对比一下:

func main() {

	s1 := make([]int, 5)
	s1 = []int{1, 2, 3, 4, 5}
	fmt.Printf("s1地址  =  %p , s1: %v \r\n", &s1, s1)

	for k, v := range s1 {
		fmt.Printf("s1[%d]地址  =  %p , s1: %v \r\n", k, &s1[k], v)
	}

	myModify(s1)
	fmt.Printf("s1地址  =  %p , s1: %v \r\n", &s1, s1)

}

func myModify(ss []int) {

	ss[2] = 8
	ss[3] = 9
	fmt.Printf("ss地址  =  %p , s1: %v \r\n", &ss, ss)
	for k, v := range ss {
		fmt.Printf("ss[%d]地址  =  %p , s1: %v \r\n", k, &ss[k], v)
	}
}

查看效果

根据上述效果,我们可以看到,s1 和 ss ,只是自己变量的地址不同,但是自己指向的底层数组的内存完全相同

平时工作中,这里就需要注意了,你以为的你以为真不可能不是这样的!!

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

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

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

相关文章

【自省】线程池里的定时任务跑的可欢了,可咋停掉特定的任务?

客户端抢到分布式锁之后开始执行任务,执行完毕后再释放分布式锁。持锁后因客户端异常未能把锁释放,会导致锁成为永恒锁。为了避免这种情况,在创建锁的时候给锁指定一个过期时间。到期之后锁会被自动删除掉,这个角度看是对锁资源的…

Going Home(二分图最大权匹配KM算法)

C-Going Home_2022图论班第一章图匹配例题与习题 (nowcoder.com) 在网格地图上有n个小人和n座房子。在每个单位时间内,每个小人都可以水平或垂直地移动一个单位步到相邻点。对于每个小矮人,你需要为他每走一步支付1美元的旅费,直到他进入一所…

Git命令笔记,下载、提交代码、解决冲突、分支处理

下载代码,复制https地址到本地文件夹,鼠标右键选择git bash后输入命令 git clone https://gitee.com/View12138/ViewFaceCore.git 下载后初始化:git init 下载代码后不运行报错(如下),需要执行初始化命令…

Google ProtoBuf的使用

Google的protobuf太好用了,又小,读写又快 跑步快慢受鞋的影响太大了,但是造鞋的工具研究起来还是很有难度的,百度真是充斥的大量的转载文件,不管能不能用、能不能看懂,反正是各种转载,有的连错…

2023年企业固定资产管理怎么破局?

2022年已经在风雨中过去,转眼我们迎来了2023年。过去的一年,固定资产管理的痛依旧历历在目,如何让新的一年中,固定资产管理工作有所突破,不再承受固定资产资产管理的痛处,是每个企业管理者和企业固定资产管…

snap打包初步了解

前言 和snap比较类似的有三种打包方式: Snap Flatpak appimage Appimage是将所有的资源打包在一起,以一个类似与独立exe的方式执行,虽然简单使用,但是解压资源和本地缓存数据都比较麻烦。 Flatpak和snap十分类似,但…

XXE无回显攻击详解

今天继续给大家介绍渗透测试相关知识,本文主要内容是XXE无回显攻击详解。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未授权设…

怎么把element的tootip设置为点击后出现提示框,且在提示框里面放其他元素,vue2动态给对象添加属性并实现响应式应答,样式穿透

怎么把element的tootip设置为点击后出现提示框 我目前有一个需求,就是要点击文字才会出现提示框,而不是hover上去就以后,找资料看文档,看了半天让我终于实现了,其实也不难,可能是最开始我没有理解value&am…

Akka 进阶(一)Dispatcher调度器

目录一 Dispatcher 任务分发1.1 理解什么是Dispatcher1.2 Executor的分类1.3 基本使用1.4 其他类型的调度器在Akka中,Actor的消息通信和任务执行建立在一个完全透明的调度机制之上,它屏蔽了底层线程(池)的实现细节,几乎…

Java: static,final,代码块 的详解

Java: static,final,代码块 的详解 每博一文案 山本文绪说过这样一句话:哪些决定放弃了的事,就请放弃得干干净净。哪些决定再也不见面的人,就真 的不要再见面了,不要再做背叛自己的事,如果想要…

CentOS7迷你版安装Redis并配置基础信息

1. 安装gcc、wget依赖 yum install gcc yum install wget 2. 使用命令:wget http://download.redis.io/releases/redis-6.2.5.tar.gz 下载安装包,注意要先cd到要下载到的目标位置) 3. tar -zxvf redis-6.2.5.tar.gz 解压压缩包 4. cd redis-…

学习周报-20221223

文章目录一 Linux的ACL访问控制列表一 基础概念1.1 起因1.2 系统支持1.3 相关定义二 查看ACL权限2.1 简单查看2.2 详细查看2.3 具体配置三 更改ACL权限3.1 添加或修改ACL3.2 输出和输入3.3 设置ACL掩码3.4 递归修改ACL3.5 删除ACL3.6 控制默认ACL权限二 Linux磁盘分区中物理卷&…

zabbix6.0安装教程(七):从web界面安装

zabbix6.0安装教程(七):从web界面安装 目录一、欢迎主界面二、先决条件检查三、配置数据库连通性四、配置本章节提供有关Zabbx Web界面的部署步骤说明。Zabbix 前端是由PHP语言编写,所以其网页服务的运行需要支持PHP语言的网站服务…

Allegro如何任意角度走线操作指导

Allegro如何任意角度走线操作指导 Allegro支持在PCB上进行任意角度走线,尤其是在高速设计的时候,尤为常见,如下图 具体操作如下 选择add connect命令Find选择Cline segs

谷歌要给移动VR定规矩

代号牛轧糖的最新安卓7.0手机操作系统发布两天后,谷歌公司开发的虚拟现实(VR)平台Daydream(下称“白日梦”)也将在未来几周推出。与平台一同推出的,还有来自Hulu和YouTube等视频网站“网红”们的全新视频内…

【软件工程】实验3:软件详细设计

CAM系统的类图 CAM系统的顺序图 CAM系统模拟实现(CAM工具库封装) 1、代码运行界面 (1)根据提示输入要加工的图形类型 (2)J-Soft软件会根据输入的数字提示用户输入不同的图形参数,图形参数输入…

函数栈帧(栈区)

函数栈帧(栈区)一.前言二.main函数空间的开辟(函数调用是如何做到的)三.main函数内部的变量初始化(局部变量是如何创建的以及为什么是随机值)四.main函数内部的函数创建1.函数是如何传参的2.传参的顺序以及…

物联网通信技术原理第2章 无线通信技术(期末重点)

目录 2.1 无线通信基本知识 2.1.2 无线通信的特点 2.2 无线信道 2.2.1 恒参无线信道举例 2.2.2 恒参无线信道特性及其对信号传输的影响 1. 幅度—频率畸变 2. 相位—频率畸变​编辑 2.2.3 随参无线信道距离 1、短波电离层反射 2、对流层散射信道 2.2.4 随参信道特性及…

漏洞深度分析|Apache Karaf 4.2.16 存在JNDI 注入漏洞

项目地址 GitHub - apache/karaf: Mirror of Apache Karaf 项目介绍 Apache Karaf是一个模块化运行时,支持多种框架和编程模型(REST/API、web、spring boot 等)。它提供了统包功能,您可以毫不费力地直接利用这些功能&#xff0…

戴维南定理

定理内容:任意二端口直流网络都可以被一个等效电路替换,这个等效电路只包含一个电压源和一个串联电阻,如图1所示。 图1 戴维南定理的作用 1、分析含有非串联或非并联电源的网络 2、用最少数量的元件实现复杂网络的端口特性(端口前…