回答

收藏

在 Go 中使用指针有什么意义?

技术问答 技术问答 485 人阅读 | 0 人回复 | 2023-09-12

我知道 Go 中的指针允许改变函数的参数,但如果只引用(使用适当的 const 或可变限定符),它会更简单吗?现在我们有指针和一些内置类型,如映射和通道隐式引用传输。+ Z/ Z$ O" z$ p* Q# Y0 G9 s
我错过了什么,还是 Go 指针只是不必要的并发症?
& p2 ]4 u3 N5 J0 b. H                                                                * ]  ~& R! S7 P. u% u
    解决方案:                                                               
2 L/ k/ }& e5 H. d! e                                                                指针有用的原因有几个。指针允许控制内存布局(影响 CPU 缓存效率)。Go 我们可以定义一个结构,所有成员都在连续内存中:. D" H, e( ?  O) u5 G  D- h# {7 L
    type Point struct {  x,y int}type LineSegment struct {  source,destination Point}
    2 F4 A+ R) K9 \# ]. j, Q
在这种情况下,Point结构嵌入在LineSegment在结构中。但是你不能总是直接嵌入数据。要支持二叉树或链表等结构,需要支持指针。
  k3 \$ S& a9 P" x& K
    type TreeNode {  value int  left  *TreeNode  right *TreeNode}
    2 f4 Y& C( N+ K; U# D7 Z- e2 _
Java、Python 没有这个问题,因为它不允许你嵌入复合类型,所以你不需要区分语法上的嵌入和方向。
& G2 Y+ M6 e' d8 [. [: x+ L使用 Go 指针解决 Swift/C# 结构问题可能的替代方法是区分相同的目的C# 和 Swiftstruct并class按照 C# 和 Swift 区分的方式。但这确实有局限性。虽然你通常可以指定函数将结构作为结构inout参数避免复制结构,但不允许您存储结构引用(指针)。这意味着当您发现该结构对创建池分配器(见下文)有用时,您永远不能将其视为引用类型。: {6 Z! }8 j) {2 A3 |
定制内存分配器使用指针,您还可以创建自己的池分配器(这是非常简单的,删除大量检查以显示原理):/ H' {. b. F1 S# P& t/ J
    type TreeNode {  value int  left  *TreeNode  right *TreeNode  nextFreeNode *TreeNode; // For memory allocation}var pool [1024]TreeNodevar firstFreeNode *TreeNode = &pool[0] func poolAlloc() *TreeNode    node := firstFreeNode    firstFreeNode  = firstFreeNode.nextFreeNode    return node}func freeNode(node *TreeNode)    node.nextFreeNode = firstFreeNode    firstFreeNode = node}
    2 R+ I6 r5 E' t& d7 q% ?
交换两个值指针也允许你实现swap. 即交换两个变量的值:
' ~5 {! f- e# p& E$ n2 j& B5 k
    func swap(a *int,b *int) {   temp := *a   *a = *b   *b = temp}6 p, y" X( ?9 W# Y; a+ I3 d
结论Java 从不能在 Google 等地方完全取代 C    系统编程的部分原因是缺乏控制内存布局和使用的能力(缓存会显著影响性能),因此无法将性能调整到相同的范围。Go 的目标是在许多领域取代 C,因此,需要支持指针。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则