【深拷贝、浅拷贝】golang函数参数传递,变量复制后,操作变量参数,是否影响原有数据?全面解析

news2025/4/15 23:32:53

Golang中深拷贝与浅拷贝的详细解析,以及变量复制、函数参数传递等场景下对新旧变量影响的总结:


一拷贝与浅拷贝的核心区别

1. 浅拷贝(Shallow Copy)

定义:仅复制数据的顶层结构,对引用类型字段(如指针、切片、映射等)仅复制其内存地址,新旧变量共享底层数据。
表现:修改新变量的引用类型字段会直接影响原变量。

type Person struct { Name string; Addr *Address }
p1 := Person{Addr: &Address{City: "Beijing"}}
p2 := p1          // 浅拷贝
p2.Addr.City = "Shanghai"  // p1.Addr.City 也被修改
2. 深拷贝(Deep Copy)

定义:递归复制所有层级的数据,包括引用类型字段指向的实际内容,新旧变量完全独立。
实现方式
• 手动逐层复制(适用于简单结构)。
• 使用copy函数复制切片。
• 反射(reflect包)或序列化(如JSON)。
• 第三方库(如copier)。

src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)  // 深拷贝切片

二、变量复制与函数参数传递的影响分析

1. 变量赋值

值类型(深拷贝)
• 包括intstringstruct(仅含值类型字段)、array等。
行为:复制数据本身,新旧变量完全独立。修改新变量不影响原变量。

a := 10
b := a  // b是a的副本
b = 20  // a仍为10

引用类型(浅拷贝)
• 包括slicemapchan、指针、接口等。
行为:复制内存地址,新旧变量共享底层数据。修改新变量会影响原变量。

s1 := []int{1, 2}
s2 := s1      // 浅拷贝
s2[0] = 100   // s1[0]也变为100
2. 函数参数传递

值传递(默认行为)
值类型参数:传递副本,函数内修改不影响原变量。
引用类型参数:传递指针/地址,函数内修改会影响原变量。

func modifySlice(s []int) { s[0] = 100 }
s := []int{1, 2}
modifySlice(s)  // s变为[100, 2]

指针传递:显式传递引用,函数内修改直接影响原变量。

func modifyInt(n * { *n = 100 }
x := 10
modifyInt(&x)  // x变为100
3. 复合结构体中的字段

• 若结构体包含引用类型字段(如切片),浅拷贝会导致共享数据。
示例

type Data struct { Slice []int }
d1 := Data{Slice: []int{1, 2}}
d2 := d1          // 浅拷贝
d2.Slice[0] = 100 // d1.Slice[0]也变为100

三、底层原理与内存管理

  1. 值类型(如intstruct):
    • 数据直接存储在栈或结构体内存中,复制时直接拷贝值。
    内存独立:每个变量拥有独立内存空间。

  2. 引用类型(如slicemap):
    • 变量存储的是指向堆内存的指针(header结构),复制时仅拷贝指针而非实际数据。
    共享内存:新旧变量指向同一块堆内存,修改会相互影响。


四、总结:何时影响原变量?

场景是否影响原变量原因
值类型变量赋值数据完全独立(深拷贝)
引用类型变量赋值共享底层数据(浅拷贝)
结构体含引用类型字段字段浅拷贝导致共享
函数传递值类型参数传递副本(深拷贝)
函数传递引用类型参数传递指针(浅拷贝)
函数内修改指针指向的值直接操作原内存地址

五、最佳实践

  1. 避免意外修改:若需独立副本,对引用类型使用深拷贝(如copy函数或序列化)。
  2. 性能权衡:深拷贝消耗更多内存和时间,仅在必要时使用。
  3. 函数设计:明确参数传递意图,优先使用值传递保证隔离性,或通过指针传递显式共享数据。

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

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

相关文章

RIP V2路由协议配置实验CISCO

1.RIP V2简介: RIP V2(Routing Information Protocol Version 2)是 RIP 路由协议的第二版,属于距离矢量路由协议,主要用于中小型网络环境。相较于 RIP V1,RIP V2 在功能和性能上进行了多项改进&#xff0c…

《LNMP架构+Nextcloud私有云超维部署:量子级安全与跨域穿透实战》

项目实战-使用LNMP搭建私有云存储 准备工作 恢复快照,关闭安全软件 [rootserver ~]# setenforce 0[rootserver ~]# systemctl stop firewalld搭建LNMP环境 [rootserver ~]# yum install nginx mariadb-server php* -y# 并开启nginx服务并设置开机自启 [r…

3DMAX笔记-UV知识点和烘焙步骤

1. 在展UV时,如何点击模型,就能选中所有这个模型的uv 2. 分多张UV时,不同的UV的可以设置为不同的颜色,然后可以通过颜色进行筛选。 3. 烘焙步骤 摆放完UV后,要另存为一份文件,留作备份 将模型部件全部分成…

【新人系列】Golang 入门(十三):结构体 - 下

✍ 个人博客:https://blog.csdn.net/Newin2020?typeblog 📝 专栏地址:https://blog.csdn.net/newin2020/category_12898955.html 📣 专栏定位:为 0 基础刚入门 Golang 的小伙伴提供详细的讲解,也欢迎大佬们…

Spring Boot 自定义商标(Logo)的完整示例及配置说明( banner.txt 文件和配置文件属性信息)

Spring Boot 自定义商标(Logo)的完整示例及配置说明 1. Spring Boot 商标(Banner)功能概述 Spring Boot 在启动时会显示一个 ASCII 艺术的商标 LOGO(默认为 Spring 的标志)。开发者可通过以下方式自定义&a…

Ubuntu虚拟机Linux系统入门

目录 一、安装 Ubuntu Linux 20.04系统 1.1 安装前准备工作 1.1.1 镜像下载 1.1.2 创建新的虚拟机 二、编译内核源码 2.1 下载源码 2.2 指定编译工具 2.3 将根文件系统放到源码根目录 2.4 配置生成.config 2.5 编译 三、安装aarch64交叉编译工具 四、安装QEMU 五、…

【蓝桥杯】2025省赛PythonB组复盘

前言 昨天蓝桥杯python省赛B组比完,今天在洛谷上估了下分,省一没有意外的话应该是稳了。这篇博文是对省赛试题的复盘,所给代码是省赛提交的代码。PB省赛洛谷题单 试题 A: 攻击次数 思路 这题目前有歧义,一个回合到底是只有一个…

【数据结构_4下篇】链表

一、链表的概念 链表,不要求在连续的内存空间,链表是一个离散的结构。 链表的元素和元素之间,内存是不连续的,而且这些元素的空间之间也没有什么规律: 1.顺序上没有规律 2.内存空间上也没有规律 *如何知道链表中包…

音视频 五 看书的笔记 MediaCodec

MediaCodec 用于访问底层媒体编解码器框架,编解码组件。通常与MediaExtractor(解封装,例如Mp4文件分解成 video和audio)、MediaSync、MediaMuxer(封装 例如音视频合成Mp4文件)、MediaCrypto、Image(cameraX 回调的ImageReader对象可以获取到Image帧图像,可转换成YU…

ubuntu 系统安装Mysql

安装 mysql sudo apt update sudo apt install mysql-server 启动服务 sudo systemctl start mysql 设置为开机自启 sudo systemctl enable mysql 查看服务状态 (看到类似“active (running)”的状态信息代表成功) sudo systemctl status mysql …

selenium快速入门

一、操作浏览器 from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By# 设置选项 q1 Options() q1.add_argument("--no-sandbo…

Redis:线程模型

单线程模型 Redis 自诞生以来,一直以高性能著称。很多人好奇,Redis 为什么早期采用单线程模型,它真的比多线程还快吗? 其实,Redis 的“快”并不在于并发线程,而在于其整体架构设计极致简单高效,…

Transformer模型解析与实例:搭建一个自己的预测语言模型

目录 1. 前言 2. Transformer 的核心结构 2.1 编码器(Encoder) 2.2 解码器(Decoder) 2.3 位置编码(Positional Encoding) 3. 使用 PyTorch 构建 Transformer 3.1 导入所需的模块: 3.2 定…

springboot框架集成websocket依赖实现物联网设备、前端网页实时通信!

需求: 最近在对接一个物联网里设备,他的通信方式是 websocket 。所以我需要在 springboot框架中集成websocket 依赖,从而实现与设备实时通信! 框架:springboot2.7 java版本:java8 好了,还是直接…

ES6学习03-字符串扩展(unicode、for...of、字符串模板)和新方法()

一、字符串扩展 1. eg: 2.for...of eg: 3. eg: 二。字符串新增方法 1. 2. 3. 4. 5.

目前状况下,计算机和人工智能是什么关系?

目录 一、计算机和人工智能的关系 (一)从学科发展角度看 计算机是基础 人工智能是计算机的延伸和拓展 (二)从技术应用角度看 二、计算机系学生对人工智能的了解程度 (一)基础层面的了解 必备知识 …

Flutter 2025 Roadmap

2025 这个路线图是有抱负的。它主要代表了我们这些在谷歌工作的人收集的内容。到目前为止,非Google贡献者的数量超过了谷歌雇佣的贡献者,所以这并不是一个详尽的列表,列出了我们希望今年Flutter能够出现的所有令人兴奋的新事物!在…

[数据结构]排序 --2

目录 8、快速排序 8.1、Hoare版 8.2、挖坑法 8.3、前后指针法 9、快速排序优化 9.1、三数取中法 9.2、采用插入排序 10、快速排序非递归 11、归并排序 12、归并排序非递归 13、排序类算法总结 14、计数排序 15、其他排序 15.1、基数排序 15.2、桶排序 8、快速排…

第16届蓝桥杯c++省赛c组个人题解

偷偷吐槽: c组没人写题解吗,找不到题解啊 P12162 [蓝桥杯 2025 省 C/研究生组] 数位倍数 题目背景 本站蓝桥杯 2025 省赛测试数据均为洛谷自造,与官方数据可能存在差异,仅供学习参考。 题目描述 请问在 1 至 202504&#xff…

记一次InternVL3- 2B 8B的部署测验日志

1、模型下载魔搭社区 2、运行环境: 1、硬件 RTX 3090*1 云主机[普通性能] 8核15G 200G 免费 32 Mbps付费68Mbps ubuntu22.04 cuda12.4 2、软件: flash_attn(好像不用装 忘记了) numpy Pillow10.3.0 Requests2.31.0 transfo…