Goland的值与引用类型
在新的项目中,用到的Goland。以前用Python做项目,Python基本变量的赋值是引用重定向。Goland有些不一样,这里做个测试
直接利用打印变量值、地址的方式确认变量拷贝情况
1 | package main |
1 | 输出结果 |
分析
先看第一组结果,简单int变量t,重新赋值为2后,在内存中的地址不变。与Python不同,Python简单对象赋值是引用重定向,引用一个新的对象,会改变id(obj)的结果。Goland是在原对象的基础上修改,改变原对象中的内容。函数的传参、返回值都会拷贝一个新对象,修改拷贝的对象不影响原对象。
再看第二组结果,切片类型l,打印第一个数值是变量地址,后面接的是[len/cap]数组内存地址,切片独享保留着对数组内存地址的引用。第二次对切片赋值,同样的对象地址不变,其len、cap、数组地址发生变化。在函数listTest中,形参同样会生成一个新的对象,切片拷贝对象的len、cap、数组内存地址与元对象一致,如果改变拷贝切片中的元素,由于其引用同一个连续数组内存,原对象上也会得到体现,最后main中l[0]=99
再看第三组结果,map类型,打印的第一个值是map变量的地址,第二个参数是map对象引用的数据块地址。同样的,map对象作为形参,会拷贝出一个新对象,与list类似,新老对象引用的数据块地址一致,修改拷贝对象数据块中的数据,会影响老对象的数据。
总结
- Goland对存在的对象重新赋值,会改变原对象内存中的数据,与Python引用重定向相区别
- Goland中slices、map、channel为引用类型,其余简单类型为值类型,值类型对象中空间中包含了对象所需的全部内容,引用类型除了基本信息外还引用着一块可以共享的数据块
- Goland对象作为函数参数、函数返回值、对象间赋值、copy等机制会从老对象拷贝出一个新的对象。这里是浅拷贝机制,值类型完全复制,共用引用数据块,复制引用地址。
- 修改拷贝对象时,拷贝对象是引用类型,且修改的是引用数据块中的数据,会影响所有引用该数据块引用对象,这里容易出bug。
- 深拷贝可考虑序列化、反序列化来实现,深拷贝都比较耗时,非必须不建议使用