不要在说go存在引用传递了

news/2024/4/25 22:12:06/文章来源:https://blog.csdn.net/weixin_51991615/article/details/130345352

Go是引用传递还是值传递?

先总结结论:go语言中,所有的参数传递全都是值传递!!!,最终传递的都是一个副本,或者说拷贝了一份。

可以看一下人家官方文档怎么解释的:

As in all languages in the C family, everything in Go is passed by value. That is, a function always gets a copy of the thing being passed, as if there were an assignment statement assigning the value to the parameter. For instance, passing an intvalue to a function makes a copy of theint, and passing a pointer value makes a copy of the pointer, but not the data it points to

翻译过来就是:

与 C 家族的所有语言一样,Go 中的所有内容都是按值传递的。也就是说,一个函数总是得到被传递的东西的副本,就好像有一个赋值语句将值赋给参数一样。例如,将int值传递给函数会生成 的副本int,传递指针值会生成指针的副本,但不会复制它指向的数据。

什么是值传递?

将实参的值传递给形参,形参是实参的一份拷贝,实参和形参的内存地址不同。函数内对形参值内容的修改,是否会影响实参的值内容,取决于参数是否是引用类型

什么是引用传递?

将实参的地址传递给形参,函数内对形参值内容的修改,将会影响实参的值内容。Go语言是没有引用传递的,在C++中,函数参数的传递方式有引用传递。

下面分别举三个例子

  • 值类型的例子,go语言中,基本类型以及数组类型都是值类型,意味着它们是被复制一份给函数。
// 这个容易理解,传递的是x的副本,函数内部的改变不影响外面的变量
func main() {x := 1fmt.Println(x) // 输出 1modify(x)fmt.Println(x) // 仍然输出 1,因为修改的是 x 的副本
}func modify(x int) {x = 2
}
  • 引用类型的例子,map、slice、channel都是引用类型,它们的底层实际都是一个指针,传递的是指针,比如slice是一个数组指针,map变量的本质的是指针*hmap,channel变量本质是指针*hchan。
package mainimport "fmt"func main() {var s = []int64{1, 2, 3}fmt.Printf("直接对原始切片取地址%v \n", &s)fmt.Printf("原始切片的内存地址: %p \n", s)fmt.Printf("原始切片第一个元素的内存地址: %p \n", &s[0])modifySlice(s)fmt.Printf("改动后的值是: %v\n", s)
}func modifySlice(s []int64) {fmt.Printf("直接对函数里接收到切片取地址%v\n", &s)fmt.Printf("函数里接收到切片的内存地址是 %p \n", s)fmt.Printf("函数里接收到切片第一个元素的内存地址: %p \n", &s[0])s[0] = 10
}直接对原始切片取地址&[1 2 3] 
原始切片的内存地址: 0xc0000b8000 
原始切片第一个元素的内存地址: 0xc0000b8000 
直接对函数里接收到切片取地址&[1 2 3]
函数里接收到切片的内存地址是 0xc0000b8000 
函数里接收到切片第一个元素的内存地址: 0xc0000b8000 
改动后的值是: [10 2 3]

单从slice的结构体去看,slice的底层是一个数组指针,指向的是底层数组第一个元素,所以在进行传参的时候打印出来的地址一样,但是实际还是值传递,因为从modifySlice中是永远改变不了len和cap的,除非传递&slice

map的例子:

package mainimport "fmt"func main() {m := make(map[string]int)m["age"] = 1fmt.Printf("原始map的内存地址是:%p\n", &m)modifyMap(m)fmt.Printf("改动后的值是: %v\n", m)
}func modifyMap(m map[string]int) {fmt.Printf("函数里接收到map的内存地址是:%p\n", &m)m["age"] = 2
}原始map的内存地址是:0xc00000e038
函数里接收到map的内存地址是:0xc00000e048
改动后的值是: map[age:2

这个就好理解了,modify之后和之前的内存地址不一样,说明是值传递。

  • 从传递结构体和传递结构体指针讲解一下值传递
package mainimport "fmt"type Person struct {Name string
}func main() {p := &Person{Name: "aa",}modifyStruct(p)fmt.Println(p.Name) // aa
}func modifyStruct(p *Person) {p = nil
}

为什么这个打印出来是aa呢,不是传递指针了吗,为什么不是打印不是nil呢?

因为go函数传递都是值传递,即使传递了指针,实际就是对指针的一份拷贝,p = nil就是对新的指针指向的nil,并不是对原结构体指向nil,所以并不影响原结构体。

那我传递指针有什么作用呢?----->那就看下一个例子

package mainimport "fmt"type Person struct {Name string
}func main() {p := &Person{Name: "aa",}modifyStruct(p)fmt.Println(p.Name) // bb
}func modifyStruct(p *Person) {p.Name = "bb"
}

这个为什么就是bb了呢?

因为拷贝过来的指针指向了原结构体的name字段,虽然拷贝了指针,但是这个指针指向了原来结构体的name字段,也就是aa,我将aa改变成了bb,所以最终影响了原结构体,实际上还是值传递,只是指向了原结构体字段,有了具体指向。

所以,go中的传递全都是值传递!!!可别说是引用传递了!!!

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握这些移动测试技巧,棘手的问题也能游刃有余解决了

目录:导读 引言 一、测试的程序 二、功能测试点 三、移动端安卓环境变量 性能测试 四、实操通过USB连接到手机设备 五、adb操作命令 写在最后 引言 你是否曾经遇到过打开一个移动应用后出现各种问题,比如卡顿、闪退等? 这些问题可能会…

重塑元宇宙体验!元宇宙实时云渲染解决方案来了

元宇宙作为人工智能、云计算和数字孪生等前沿技术的结合体,近年来越发受到各大企业重视。 元宇宙的应用场景层出不穷,不仅包括营销推广场景,还有品牌活动和电商销售,能有效提升品宣和商业转化效果。 元宇宙也具有极大的建设价值…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试,识别网络安全漏洞,为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作,这就是为什么他们被称为道德黑客或网络安全…

setup,ref,reactive

初识setup 1.理解:Vue3.0中一个新的配置项,值为一个函数。 2.setup是所有Composition API(组合API)“表演的舞台”。 3.组件中所用到的:数据、方法等等,均要配置在setup中。 4.setup函数的两种返回值: 1.若返回一个对象,则对象中的属性、…

软件测试,想找一份20k以上的工作需要掌握哪些知识?

都知道IT行业是高薪人员的聚集地,但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛,想要突破就必须掌握更多的技能。 因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极…

[网络原理] 详解Cookie与Session

做好准备,迎接所有的成功吧 文章目录 1. Cookie的概念2. Session的概念3. Cookie与Session的关联与区别3.1 关联3.2 区别 4. Cookie与Session中的核心方法 1. Cookie的概念 Cookie是用户首次登陆网站成功之后,对应页面的服务器会返回给用户一个身份标识,被保存在用户主机的硬盘…

自动驾驶方案及相关对标

华为: 2021年4月18日,在华为智能汽车解决方案BU新品发布会上,华为智能汽车解决方案BU总裁王军表示,华为要持续加大对汽车行业的投入,今年在研发上的投资将达到10亿美元,未来每年保持30%左右增长&#xff0…

工程化:vite4+vue3里面的less预处理的mixin,when和伪元素的使用研究

本文的起因 项目的重构,之前的语法是scss,新项目选型选的less,两种基本的使用是差不多的,细节方面有很大的差异,今天拎出来重点的细说。。。 区别 *.scss *.less mixin .bg-dp(@number: 0) {

一文讲清莱迪斯 LCMXO2-4000HC-4BG256I 可编程逻辑FPGA 特性及运用领域

一文讲清lattice莱迪斯深力科 LCMXO2-4000HC-4BG256I 可编程逻辑FPGA 特性及运用领域 适用于低成本的复杂系统控制和视频接口设计开发,满足了通信、计算、工业、消费电子和医疗市场所需的系统控制和接口应用。 瞬时启动,迅速实现控制——启动时间小于1m…

AI数字人产品“世优BOTA”发布会落幕,世优科技纪智辉演讲回顾

4月20日,世优科技式发布了新一代AI数字人产品——“世优BOTA”。在会上,世优科技创始人纪智辉介绍了数字人技术、驱动形式、数字人应用、“世优BOTA”的前世今生及未来。 以下是纪智辉的演讲内容概要: 各位嘉宾、各位朋友:大家下…

【 Spring Mybatis 复杂的查询操作 】

文章目录 引言一、参数占位符 #{} 和 ${}二、SQL 注入三、like 模糊查询四、返回类型:resultType 和 resultMap五、多表查询 引言 前面我们已经学会了使用 Mybatis 进行增,删,改操作,也实现了简单的查询操作 !下面我们…

mysql主从复制搭建--待实践完善

一、什么是mysql主从复制 参考链接:MySQL主从介绍_rain_yunlx的博客-CSDN博客 Linux下搭建Mysql主从复制详细步骤(Mysql版本5.7.35)_linuxmysql主从_Direct_的博客-CSDN博客 Linux环境MySQL数据库主从复制保姆级教程_linux主从复制_小学生…

【SWAT水文模型】ArcSWAT输入准备:土地利用/土壤/气象数据

ArcSWAT输入准备:土地利用/土壤/气象数据 1 土地利用数据的处理1.1 数据下载 2 土壤库建立2.1 数据下载 3 气象数据库参考 1 土地利用数据的处理 1.1 数据下载 下载地址如下: 中科院1km土地利用数据 清华大学高精度土地利用数据 2 土壤库建立 SW…

如何将pdf图片文字转换成word 文字word图片怎么转换pdf

如今大家在工作中常常会运用到电脑来办公,电脑的运用大大提高了我们的工作效率,在带来机会的同时同样也带来了新挑战。 pdf图片怎么转换成word文档?PDF格式是一种常用的文档格式,它可以保持文档内容和格式的完整性,但是…

【UE】制作简单的山脉地形

在上一篇博客中(【UE】使用Quixel Bridge下载免费贴图),介绍了如何下载免费贴图,本篇博客介绍如何使用这些贴图制作地形贴图。 1. 创建地形 2. 用雕刻工具绘制地形 3. 新建两个材质函数,分别命名为“GrassAuto”、“R…

离散数学期末复习第一章 数理逻辑

离散数学 离散数学是研究各种各样的离散量的结构及离散量之间的关系一门学科,是计算机科学中基础理论的核心课程。 什么是连续变量? 在一定区间内可以任意取值的变量叫连续变量,其数值是连续不断的,相邻两个数值可作无限分割&a…

在线问诊小程序系统方案以及价值

方案价值zlzwgz0127 1.扩大医院流量 a.预约到院 在线展示专家的介绍,更能彰显实力,吸引患者来院就医, 用户可选择在线问诊和预约到院 b.社区团购导流 与我们合作社区团购给医院的体检产品导流 c.专家直播导流 通过专家直播吸引潜在患者…

观察者设计模式(Observer Design Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

文章目录 概念组成角色相关图示示例代码框架中的运用适用场景 概念 观察者设计模式(Observer Design Pattern)是一种行为型设计模式,它定义了一种对象间的一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当…

机器学习 Rider数据集分析和预测

介绍数据集 ride_id:乘车ID rideable_type:乘车类型 started_at:开始日期 ended_at :结束日期 start_station_name:开始站的名字 start_station_id:开始站的ID end_station_name:结束站的名字 …

内网渗透之横向移动rdpwinrmwinrsspnkerberos

0x00 准备 环境:god.org cs上线 win2008web 提权利用ms14-058 抓取hash和明文密码(当获取到其他主机就重复提权和抓取密码) 扫描存活主机,扫描端口 代理转发-转发上线,生成反向连接木马,绑定监听器,上传至web根目录(方…