Golang对比Java、python为什么要保留指针

为什么要用指针?

平时我们在Golang使用指针一般是为了以下的情况:

  • 方法直接修改原来对象
  • 保证参数传递的自由,可以在传递重量级对象时使用指针

但Go 保留指针不仅仅是为了解决传递参数的问题,还跟它的语言特性有密不可分的联系。

值语义

Go 里面的变量是值语义 ,这个跟 C/C++是一脉相承的。比如一个结构体变量赋值给另外一个变量就是一次内存拷贝,而不是只拷贝一个指针,因此需要指针来表达引用语义,关于拷贝的具体实现可以了解直接值部与间接值部的实现

关于值语义(value semantics):值语义指的是对象的拷贝与原对象无关,就像拷贝 int 一样。C++ 的内置类型(bool/int/double/char)都是值语义,标准库里的 complex<> 、pair<>、vector<>、map<>、string 等等类型也都是值语意,拷贝之后就与原对象脱离关系。同样,Java 语言的 primitive types 也是值语义。

优点

复杂的高级类型占用的内存往往相对较大,存储在 heap 中,GC 回收频率相对较低,代价也较大,因此传引用/指针可以避免进行成本较高的复制操作,并且节省内存,提高程序运行效率。

为什么要保留值语义,而不是像 Java 或者 Python 一样让复合类型默认都是指针类型呢?因为值语义带来了如下好处:

  • 结构体可以直接用来比较相等,而非比较指针,Java 里面的 == 操作符除了基本类型有用,其他类型几乎没用。
  • 与 C 语言更好地交互。Go 可以通过 cgo 与 C 语言无缝交互。Go 里面的结构体基本上不用特殊处理就能传递给 C 的函数使用。主要得益于 Go 的结构体和 C 的一样都是值类型。
  • 开发者能更好的掌控内存布局。一个结构体数组就是一段连续内存,而不是一个指针数组。
  • 减轻 GC 压力。紧凑的内存布局减少了 GC 对象的个数,比如一个100w 长度的结构体数组就是一个 GC 对象,而不是100w 个。
  • 减轻堆内存的分配压力。函数通过传值的方式传递参数后,原变量不会发生逃逸,可以被分配在栈上

Go 为了内存安全,虽然有指针,但不支持指针算数,但结合 unsafe.Pointer 也可以完成一些非常规情景下的精细内存操作。比如结合 mmap 实现堆外内存管理,runtime 里面的内存管理就是这么来的,完全不用另外用 C 语言来实现。 这也是可以使用 Go 语言来写操作系统(eggos)的原因。

总结:

Go 的指针一方面提供了引用语义,另一方面像 C 语言一样给了开发者灵活管理内存的能力。

参考链接:樊冰心:https://www.zhihu.com/question/399589293/answer/2242103027

相关推荐
Tony Bai1 小时前
“我曾想付钱给 Google 去工作”—— Russ Cox 深度访谈:Go 的诞生、演进与未来
开发语言·后端·golang
sali-tec1 小时前
C# 基于halcon的视觉工作流-章66 四目匹配
开发语言·人工智能·数码相机·算法·计算机视觉·c#
45288655上山打老虎2 小时前
C++完美转发
java·jvm·c++
Seven972 小时前
查找算法
java
路边草随风2 小时前
milvus向量数据库使用尝试
人工智能·python·milvus
hnlgzb2 小时前
安卓app开发,如何快速上手kotlin和compose的开发?
android·开发语言·kotlin
newobut2 小时前
vscode远程调试python程序,基于debugpy库
vscode·python·调试·debugpy
无敌最俊朗@3 小时前
STL-deque面试剖析(面试复习4)
开发语言
APIshop3 小时前
用 Python 把“API 接口”当数据源——从找口子到落库的全流程实战
开发语言·python
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 公务员考试在线测试系统为例,包含答辩的问题和答案
java