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

标签 pointers go

我知道 Go 中的指针允许改变函数的参数,但如果它们只采用引用(使用适当的 const 或 mutable 限定符),那岂不是更简单。现在我们有了指针和一些内置类型,如 map 和 channel ,隐式通过引用传递。

我是否遗漏了什么或者 Go 中的指针只是一个不必要的复杂问题?

最佳答案

指针之所以有用有几个原因。指针允许控制内存布局(影响 CPU 缓存的效率)。在 Go 中,我们可以定义一个所有成员都在连续内存中的结构:

type Point struct {
  x, y int
}

type LineSegment struct {
  source, destination Point
}

在这种情况下,Point 结构嵌入在 LineSegment 结构中。但是你不能总是直接嵌入数据。如果要支持二叉树或链表等结构,则需要支持某种指针。

type TreeNode {
  value int
  left  *TreeNode
  right *TreeNode
}

Java、Python 等没有这个问题,因为它不允许你嵌入复合类型,所以不需要在语法上区分嵌入和指向。

使用 Go 指针解决的 Swift/C# 结构问题

一个可能的替代方法是像 C# 和 Swift 那样区分 structclass。但这确实有局限性。虽然您通常可以指定函数将结构作为 inout 参数以避免复制结构,但它不允许您存储对结构的引用(指针)。这意味着当您发现它有用时,您永远不能将结构视为引用类型,例如创建一个池分配器(见下文)。

自定义内存分配器

您还可以使用指针创建自己的池分配器(这非常简化,删除了许多检查以显示原理):

type TreeNode {
  value int
  left  *TreeNode
  right *TreeNode

  nextFreeNode *TreeNode; // For memory allocation
}

var pool [1024]TreeNode
var firstFreeNode *TreeNode = &pool[0] 

func poolAlloc() *TreeNode {
    node := firstFreeNode
    firstFreeNode  = firstFreeNode.nextFreeNode
    return node
}

func freeNode(node *TreeNode) {
    node.nextFreeNode = firstFreeNode
    firstFreeNode = node
}

交换两个值

指针还允许您实现 swap。那就是交换两个变量的值:

func swap(a *int, b *int) {
   temp := *a
   *a = *b
   *b = temp
}

结论

Java 一直无法在 Google 等地方完全取代 C++ 进行系统编程,部分原因是由于缺乏控制内存布局和使用的能力(缓存未命中会影响性能),因此无法将性能调整到相同的范围显著地)。 Go 的目标是在许多领域取代 C++,因此需要支持指针。

关于pointers - 在 Go 中使用指针有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1863460/

相关文章:

arrays - 如何分配 channel 数组

go - go1.4中是否有必要放弃堆栈上太大的变量以避免堆栈复制?

c++如何将迭代器指针传递给需要引用对象的函数

c - mallocing 是否等同于具有指定数组大小的指针

c - 结构指针实现方法

json - HTTP 请求、JSON、重用连接

c中通过指针计算数组长度,答案是错误的

c++ - 如何在数组和指针之间交换 C++

go - 动态更新Redis排序集中的元素等级

go - 将CreationTimeStamp类型转换为字符串