Go语言中的值传递和引用传递 附: 内存地址分析

news2024/12/25 9:00:47

在学习Go语言函数部分遇到了引用传递和值传递,与C颇为类似,浅谈一下自己对Go语言中的值传递和引用传递的理解。

一、数组—值传递

我们用Go语言中的数组作为样例,来理解值传递的过程。

代码

package main

import "fmt"

func main() {
    arr1 := [4]int{1, 2, 3, 4}
	fmt.Printf("arr1-p: %p\n", &arr1)
	fmt.Printf("arr1[0]-p: %p\n", &arr1[0])
	fmt.Println("arr1-1: ", arr1)
    update(arr1)
	fmt.Println("arr1-2: ", arr1)
}

func update(arr2 [4]int) {
	fmt.Println("arr2-1: ", arr2)
	arr2[0] = 5
	fmt.Println("arr2-2: ", arr2)
	fmt.Printf("arr2-p: %p\n", &arr2)
	fmt.Printf("arr2[0]-p: %p\n", &arr2[0])
}

结果

arr1-p: 0xc0000141a0
arr1[0]-p: 0xc0000141a0
arr1-1:  [1 2 3 4]
arr2-1:  [1 2 3 4]
arr2-2:  [5 2 3 4]
arr2-p: 0xc0000141e0
arr2[0]-p: 0xc0000141e0
arr1-2:  [1 2 3 4]

通过运行,我们可以看到,在Go语言中对于数组传递,属于值传递,当然基本类型以及结构体在Go中也是数值传递。我们画图来理解上述结果~

 

从输出结果我们可以看出,arr1 和 arr2 对指向的地址与数组中的首个元素的地址相一致,说明变量 arr1 和 arr2 对应的就是数组中首元素的地址。在函数传递过程中,arr2 的数据是从 arr1 赋值或者拷贝过来的,分别存在于内存的不同空间中,所以修改 arr2 并不会对 arr1 产生影响。

补充:这里我们了解到,arr1 的地址和索引为 0 的元素的地址相同,也就是 arr1 的与索引为 0 的元素在内存的同一位置,arr1 所对应的数值为 [1 2 3 4],同理 arr2 也是如此。

对于值传递来说,在传递过程中,传递的是数据的副本,在其它函数中修改数据,并不会对原始数据产生影响。

二、切片—引用传递

我们将Go语言中与数组非常相似的切片类型作为样例,来理解引用传递的过程。

代码

package main

import "fmt"

func main() {
	s1 := []int{1, 2, 3, 4}
	fmt.Println("s1:", s1)
	update2(s1)
	fmt.Println("s1:", s1)
	fmt.Printf("s1: %p\n", s1)
    fmt.Printf("s1-p: %p\n", &s1)
}

func update2(s2 []int) {
	fmt.Println("s2: ", s2)
	s2[0] = 5
	fmt.Println("s2: ", s2)
	fmt.Printf("s2: %p\n", s2)
    fmt.Printf("s2-p: %p\n", &s2)
}

结果

s1: [1 2 3 4]
s2:  [1 2 3 4]
s2:  [5 2 3 4]
s2: 0xc0000141a0
s2-p: 0xc0000080a8
s1: [5 2 3 4]
s1: 0xc0000141a0
s1-p: 0xc000008078

通过运行结果我们可以看到,切片在Go中属于引用传递,当然还有很多引用传递的类型,比如 map、chan等等。我们看图理解~

分析运行结果,我们能够得知,不论是 s1 还是 s2 都是指向内存中的同一地址,所以当 s2 在操作索引为 0 的数据内容时,会使得原始数据产生改变,也就是 s1 原本的数据发生变化。

补充:这里变量 s1 和 s2 的内存地址并不相同,一个是 0xc000008078,另一个是 0xc0000080a8,但是相同的是,变量 s1 和 s2 的内存地址存储的内容一致,都是切片首元素的地址,也就是索引为 0 的元素的地址。

那么对于引用传递来说,变量在内存中的存放在一定的地址上,修改变量实际上就是修改变量所在地址处的内容。

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

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

相关文章

[附源码]计算机毕业设计springboot基于Java的员工管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

[附源码]SSM计算机毕业设计校园闲置物品租赁系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Pytest接口测试框架实战项目搭建(二)

一、前言 业务系统的登录均要经过统一登录系统S,本篇演示统一登录处理,一个是内部业务系统C(其余内部业务系统AB用的都是相同账号密码),一个是外部用户使用的系统W,因为账号密码以及headers信息都不一样&am…

DCDC--Burst Mode和Pulse Skipping Mode

1、Burst Mode和Pulse Skipping Mode(PSM)的区别 Burst Mode ≠ Pulse Skipping Mode,论坛有人认为Burst Mode就是Pulse Skipping Mode,这是不对的。 以LTC3624为例: Burst Mode operation provides the highest ef…

大数据(9h)FlinkSQL双流JOIN、Lookup Join

文章目录1、环境2、Temporal Joins2.1、基于处理时间(重点)2.1.1、设置状态保留时间2.2、基于事件时间3、Lookup Join(重点)4、Interval Joins(基于间隔JOIN)重点是Lookup Join和Processing Time Temporal …

SpringBoot+Vue实现前后端分离的餐饮点餐系统

文末获取源码 开发语言:Java 使用框架:spring boot 前端技术:JavaScript、Vue.js 、css3 开发工具:IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库:MySQL 5.7/8.0 数据库管理工具:phpstudy/Navicat JD…

线性表01- 数组与简易接口设计

线性表的定义 线性表: 具有n个相同类型元素的有限序列 n>0 线性表的元素特点是有索引, 可以通过索引快速查找到元素. a1是a2的前驱, a2是a1的后继 常见的线性表 数组链表栈队列哈希表 (散列表) 数组 数组是一种顺序存储的线性表, 所有的元素的内存地址是连续的. int arr…

Python用广义加性模型GAM进行时间序列分析

每当你发现一个与时间对应的趋势时,你就会看到一个时间序列。我们围绕广义加性模型GAM技术进行一些咨询,帮助客户解决独特的业务问题。研究金融市场表现和天气预报的事实上的选择,时间序列是最普遍的分析技术之一,因为它与时间有着…

matlab图像的运算有点运算、代数运算、逻辑运算和几何运算

1.图像的点运算 2.图像的代数运算 3.图像的逻辑运算 4.图像的几何运算 一、图像的点运算 图像的点运算:对图像中的每个像素值进行计算,从而改善图像显示效果的操作,常用于改变图像的灰度范围及分布,有时也被称为对比度增强和拉伸…

Arduino开发实例-DIY酒精浓度检测计

DIY酒精浓度检测计 在本文中,将详细介绍如何创建一个简单的酒精检测器。 它可以在各种应用领域中使用。市场上有许多先进的酒精传感器,价格合理,但我们在这里使用一些基本的微控制器来制作这个项目,如 Arduino、LED、蜂鸣器和 MQ3 酒精传感器。 1、MQ-3传感器介绍 MQ-3传…

外卖项目(项目优化2)11---读写分离

读:查询的操作 目录 一、Mysql主从复制 172 1.1Mysql主从复制_配置主库Master&从库Slave 173 配置:主库Master: 配置:从库Slave 二、读写分离案例 175 2.1背景 2.2Sharding-JDBC介绍 2.3读写分离案例---入门案例 17…

Magic Leap 2设计和开发幕后花絮

Magic Leap今年发布新款AR头显Magic Leap 2,相比于上一代Magic Leap 1,新品更专注于B端场景,自公布以来,Magic Leap不仅对公司策略、理念更加透明,也不断公开ML2产品设计背后的思考。相比于ML1,ML2的设计有…

里P7告诉你,接口测试真的很简单,有手就行

一、什么是接口测试? 所谓接口,是指同一个系统中模块与模块间的数据传递接口、前后端交互、跨系统跨平台跨数据库的对接。而接口测试,则是通过接口的不同情况下的输入,去对比输出,看看是否满足接口规范所规定的功能、…

windows bat批处理文件,实现某个软件的重启

bat批处理实现软件重启功能windows环境需要明确的概念按照启动文件xxx.exe去定位某个程序的Pid根据pid杀死某个进程根据exe文件启动某个软件bat示例,杀死软件进程并重启windows环境 我这里用的是win10企业版,在基础功能上和家庭版区别不大 需要明确的概…

19uec++多人游戏【基础AI导航】

首先把这一期的资源导入一下 创建一个球体类,继承于pawn类 为其添加静态组件 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category "Components")class UStaticMeshComponent * MeshComponent; #include "Components/StaticMeshComponent.h&qu…

具备统一门户功能的内网即时通讯软件才是发展趋势

作为企业领导,我们最害怕的就是下属工作效率不高,没办法为企业带来价值,有时候并不一定是员工自身存在问题,“工欲善其事,必先利其器“正好说明了,如果我们有能力在线的员工加上强大的办公软件辅助&#xf…

如何线上登记版权?

问题一:为什么要登记版权? 告诉你一个行业秘密,其实可以不用登记版权,为什么?因为作品自完成就自动拥有版权,作者可以自己选择登记与否,不登记对版权也没有影响。这里可能有人要问了&#xff0…

xss-labs/level12

这一关首先尝试以下 <script>alert(xss)</script> 不废话 直接看源代码 很明显发现第一个输出点被转义了 根本无法通过script标签来完成弹窗 然后依然是四个隐藏表单 我们可以先试一试在不用抓包工具的前提下 我们能不能将某个隐藏表单给显示出来 构造如下 &l…

Docker的常用基础命令(详细讲解)

首选需要大家搭建好Docker环境&#xff0c;没有环境的可以查看前面的详细讲解安装Docker引擎的文章&#xff08;在CentOS上安装Docker引擎_征服bug的博客-CSDN博客&#xff09; 首先是安装好Docker 引擎 一&#xff0c;如何启动与停止引擎服务 #启动docker systemctl start do…

JAVA-GUI工具的编写-----请求篇

上节我们说到&#xff0c;我们制作了样子货的GUI&#xff0c;但是没有嵌入任何的按钮事件&#xff0c;并且上一次忘记加进去命令执行的确定按钮&#xff0c;让我们简单的回顾一下子吧 import javafx.application.Application; import javafx.collections.FXCollections; impor…