Golang深拷贝浅拷贝
Golang深拷贝浅拷贝
在了解原型设计模式之前我们需要新知道Golang的深拷贝与浅拷贝之间的区别。
推荐大家新看看Slice 和 Map那么常见的坑:https://blog.csdn.net/weixin_40165163/article/details/90707593
github:https://github.com/zhumengyifang/GolangDesignPatterns
数据结构:
//速度速值
type Speed int//风扇转速
type FanSpeed struct {Speed Speed
}//售价
type Money struct {Length float64
}//内存数量以及大小
type Memory struct {Count intMemorySize []int
}//电脑信息
type Computer struct {SystemName string //系统名字UseNumber int //使用次数Memory Memory //存储Fan map[string]FanSpeed //风扇Money Money //售价
}
浅拷贝:
接触过 Java或者C#的同学应该知道浅拷贝对于值类型的话是完全拷贝一份,而对于引用类型是拷贝其地址。也就是拷贝的对象修改引用类型的变量同样会影响到源对象。
这里Golang同理,在上述测试类型中涉及到 Slice 和 Map的修改则会互相影响。
测试1:
func ComputerStart1() {Pc1 := Computer{SystemName: "Windows",UseNumber: 1000,Memory: Memory{Count: 4, MemorySize: []int{32, 32, 32, 32}},Fan: map[string]FanSpeed{"left": {2500}, "right": {2000}},Money: Money{123.45},}//浅拷贝Pc2:=Pc1fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)//修改切片内容以及map信息影响Pc1Pc2.SystemName ="MacOs"Pc2.UseNumber =100Pc2.Memory.Count =2Pc2.Memory.MemorySize[0]=8Pc2.Memory.MemorySize[1]=8Pc2.Memory.MemorySize[2]=0Pc2.Memory.MemorySize[3]=0Pc2.Fan["left"]=FanSpeed{2000}Pc2.Fan["right"]=FanSpeed{1500}fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)
}
输入信息:
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{Windows 1000 {4 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}, Pc2:{MacOs 100 {2 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}
对于PC2的修改影响到了PC1的Slice 和 Map
测试2:
func ComputerStart2() {Pc1 := Computer{SystemName: "Windows",UseNumber: 1000,Memory: Memory{Count: 4, MemorySize: []int{32, 32, 32, 32}},Fan: map[string]FanSpeed{"left": {2500}, "right": {2000}},Money: Money{123.45},}//浅拷贝Pc2:=Pc1fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)ModifyCat(Pc2)fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)
}func ModifyCat(pc Computer) {fmt.Printf("PcInfo Pc1:%v\n", pc)pc.SystemName ="MacOs"pc.UseNumber =100pc.Memory.Count =2pc.Memory.MemorySize[0]=8pc.Memory.MemorySize[1]=8pc.Memory.MemorySize[2]=0pc.Memory.MemorySize[3]=0pc.Fan["left"]=FanSpeed{2000}pc.Fan["right"]=FanSpeed{1500}fmt.Printf("PcInfo Pc1:%v\n", pc)
}
输入:
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{MacOs 100 {2 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}
PcInfo Pc1:{Windows 1000 {4 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}, Pc2:{Windows 1000 {4 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}
这里在方法中修改PC2同样影响到了 PC1以及PC2,是因为在Golang中方法中传递的参数同样被拷贝了一份,他们修改的Slice 和 Map都是同一份地址。
那么对于浅拷贝来说如何避免这种情况的发生呢?
测试3:
func ComputerStart2() {Pc1 := Computer{SystemName: "Windows",UseNumber: 1000,Memory: Memory{Count: 4, MemorySize: []int{32, 32, 32, 32}},Fan: map[string]FanSpeed{"left": {2500}, "right": {2000}},Money: Money{123.45},}//浅拷贝Pc2:=Pc1fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)//切片以及map新空间互不影响Pc2.SystemName ="MacOs"Pc2.UseNumber =100Pc2.Memory =Memory{Count: 2, MemorySize: []int{8, 8}}Pc2.Fan =map[string]FanSpeed{"left": {2000}, "right": {1500}}Pc2.Money =Money{1000.45}fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)
}
输出:
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:{MacOs 100 {2 [8 8]} map[left:{2000} right:{1500}] {1000.45}}
既然只有Slice 和 Map会受到影响我们这里重新给定地址重新生成一个Slice和Map就可以不受影响。
深拷贝
对于深拷贝就比较好了解了,任何对象都会被完完整整的拷贝一份,拷贝对象与被拷贝对象不存在如何联系,也就不会互相影响。如果你需要拷贝的对象中没有引用类型,那么对于Golang而言使用浅拷贝就可以了。
基于序列化和反序列化来实现对象的深度拷贝:
func deepCopy(dst, src interface{}) error {var buf bytes.Bufferif err := gob.NewEncoder(&buf).Encode(src); err != nil {return err}return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}
需要深拷贝的变量必须首字母大写才可以被拷贝
测试1:
func ComputerStart4() {Pc1 := &Computer{SystemName: "Windows",UseNumber: 1000,Memory: Memory{Count: 4, MemorySize: []int{32, 32, 32, 32}},Fan: map[string]FanSpeed{"left": {2500}, "right": {2000}},Money: Money{123.45},}//深拷贝Pc2:= new(Computer)if err:= deepCopy(Pc2,Pc1);err!=nil{panic(err.Error())}fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)ModifyCat1(*Pc2)fmt.Printf("PcInfo Pc1:%v, Pc2:%v\n", Pc1, Pc2)
}
输出:
PcInfo Pc1:&{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:&{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}
PcInfo Pc1:{MacOs 100 {2 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}
PcInfo Pc1:&{Windows 1000 {4 [32 32 32 32]} map[left:{2500} right:{2000}] {123.45}}, Pc2:&{Windows 1000 {4 [8 8 0 0]} map[left:{2000} right:{1500}] {123.45}}
可以看到PC2经过浅拷贝(参数传递)在修改Slice和Map受到影响的也只有PC2和PC2的浅拷贝对象。对于PC1没有任何影响。
下一章原型设计模式:https://blog.csdn.net/weixin_40165163/article/details/90671135
Golang深拷贝浅拷贝相关推荐
- java深拷贝和浅拷贝_Java 深拷贝浅拷贝 与 序列化
一.浅拷贝.深拷贝 浅拷贝会对对象中的成员变量进行拷贝:如果是基本类型,拷贝的就是基本类型的值:如果属性是内存地址(引用类型),拷贝的就是内存地址 : 深拷贝,除了基本类型外,引用类型所引用的对象也会 ...
- Java基础 深拷贝浅拷贝
Java基础 深拷贝浅拷贝 非基本数据类型 需要new新空间 class Student implements Cloneable{private int id;private String name ...
- 原型模式与深拷贝浅拷贝
原型模式与深拷贝浅拷贝 原型模式 Java中的原型模式 简单的例子 浅拷贝 深拷贝 效率比较 JMH测试样例 测试结果 原型模式 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或 ...
- Map的putAll方法踩坑实记(对象深拷贝浅拷贝)
文章目录 问题描述 编写测试代码模拟问题场景 场景1:Map中不包含对象 场景2:Map中包含对象 什么是对象的浅拷贝深拷贝 如何实现深拷贝 问题描述 在一个产品管理系统中,产品信息需要封装一份同步业 ...
- 一篇文章彻底说清JS的深拷贝/浅拷贝
一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者. 第二类,希望扎实JS基础,将来好去面试官前秀操作的好学者. 写给第一类读者 你只需要一 ...
- JavaScript学习笔记(五)--深拷贝浅拷贝
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 本篇文章中也会简单阐述到栈堆, ...
- C++析构函数与构造函数深拷贝浅拷贝(C++初学面向对象编程)
文章目录 一.析构函数 二.C++默认生成的函数 三.构造与析构的调用顺序 四.构造函数的浅拷贝 五.构造函数的深拷贝 一.析构函数 1.析构函数的作用 对象消亡时,自动被调用,用来释放对象占用的内存 ...
- 浅谈C#深拷贝,浅拷贝
1.深拷贝与浅拷贝 拷贝即是通常所说的复制(Copy)或克隆(Clone),对象的拷贝也就是从现有对象复制一个"一模一样"的新对象出来.虽然都是复制对象,但是不同的 复制方法,复制 ...
- 真深复制python_Python深复制浅复制or深拷贝浅拷贝
简单点说 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >>> ...
- ES6中展开运算符的深拷贝浅拷贝理解(ElementUI表格点击编辑,模态框内容与表格数据一起变的问题)
项目中遇到的问题: 在elementui中表格点击按钮传值的时候,通过bus中的$emit传对象,在弹出的模态框中用bus的$on接收对象,然后对传的对象进行改变,结果发现改变了原表格的数据. 然后就 ...
最新文章
- Gin 框架学习笔记(02)— 参数自动绑定到结构体
- 【SICP练习】30 练习1.36
- 解决ArcMap启动时只停留在初始化界面的方法
- python在中小学教学中的应用-中小学Python教学的几点建议
- python中%是什么意思_python中%代表什么意思?
- linux各版本代码量,linux各版本对应溢出漏洞总结(溢出代码)
- 计算bom的准确用量
- SON Web Token设计单点登录系统
- [ESC] EnTT 学习记录 2
- centos 6.5 yum mysql 5.6_centos 6.5 yum安装 mysql 5.6
- python2和python3中encoding的差别
- LINUX安装TensorRT及特别注意事项
- Ctrix-XenApp中误删应用服务器,如何重新添加
- BP神经网络代码和原理
- Redis 下载与安装(Windows版)
- 如何制作微信小程序(三个步骤开发小程序)
- java不想被gc,Java GC 必知必会
- 板岩 Steven Slate Audio :FG-2A 压缩评测
- Ubuntu大于2T硬盘,分区并挂载
- MicroPython ESP32 ADC(模拟量转数字量)示例
热门文章
- 谈谈业务系统的监控报警
- java 对音频文件降噪_如何对音频文件降噪?闪电音频剪辑软件为音频降噪的方法...
- 【题解】洛谷P1661扩散(同LibreOJ10015) 曼哈顿距离最小生成树
- 云流送技术可以支持多人交互吗?
- ACwing 149. 荷马史诗
- 《算法竞赛进阶指南》荷马史诗
- 8.6 百度首页编写-导航栏
- 【美团校招在线考试笔试题】钱币面值组合
- Python的Method理解
- gimp 抠图_GMIC(gimp 快速抠图)V1.5.2.4 免费版