为什么切片有时会通过引用传递,有时候是通过指针?

ach*_*zot 1 pointers go

container/heapgo中的默认包中,有一个实现优先级队列的示例.

在查看示例代码时,它使用切片[]*Item,并实现heap.Interface.

我的麻烦在于以下几点.为什么某些函数使用优先级队列作为切片声明,有时作为指向切片的指针?:

func (pq PriorityQueue) Swap(i, j int) {...}
// vs
func (pq *PriorityQueue) Push(x interface{}) {...}
Run Code Online (Sandbox Code Playgroud)

为什么不总是这样(pq PriorityQueue)?在关于切片指针的另一个StackOverflow线程中,文档说切片是refence类型,那么为什么要在它们上使用指针呢?我正在遇到这样一个事实,即官方文档会说某些内容然后混合两者而不解释添加指针的问题.

感谢您的见解!

编辑:这是一个例子:

// original sample code from the docs:
func (pq *PriorityQueue) Push(x interface{}) {
    n := len(*pq)
    item := x.(*Item)
    item.index = n
    *pq = append(*pq, item)
}

// is this the same (removed pointers to slice) ?
func (pq PriorityQueue) Push(x interface{}) {
    n := len(pq)
    item := x.(*Item)
    item.index = n
    pq = append(pq, item)
}
Run Code Online (Sandbox Code Playgroud)

如果两个函数都相同,为什么现在使用指针?

Iam*_*NaN 5

Go go博客上的这篇文章解释了原因.

传递切片到功能部分:

重要的是要理解即使切片包含指针,它本身也是一个值.在封面下,它是一个包含指针和长度的结构值.它不是指向结构的指针.

因此,您需要传递指针,或者如果要使用append修改它,则需要将切片作为值返回.

如果您只想修改切片的内容,只需按值传递切片即可:

即使切片标头按值传递,标头也包含指向数组元素的指针,因此原始切片标头和传递给函数的标头副本都描述了相同的数组.因此,当函数返回时,可以通过原始切片变量看到修改后的元素.

使用追加,您正在修改切片标头.和

因此,如果我们想编写一个修改标题的函数,我们必须将它作为结果参数返回

要么:

使函数修改切片标头的另一种方法是传递指向它的指针.