为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕雪6442864 2021-10-04 16:20:47
在container/heapgo的默认包中,有一个实现优先级队列的例子。在查看示例代码时,它使用了一个切片[]*Item,并实现了heap.Interface.我的问题是下面的一点。为什么某些函数将优先级队列声明为切片,有时将其声明为指向切片的指针?:func (pq PriorityQueue) Swap(i, j int) {...}// vsfunc (pq *PriorityQueue) Push(x interface{}) {...}为什么不总是这样(pq PriorityQueue)?在另一个关于指向切片的指针的 StackOverflow 线程上,文档说切片是引用类型,那么为什么要在它们上使用指针呢?我遇到了麻烦,因为官方文档说了些什么然后将两者混合在一起,而没有解释添加指针的意义。感谢您的见解!编辑:这是一个例子:// 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)}如果两个函数相同,为什么现在使用指针?
查看完整描述

1 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

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

从将切片传递给函数部分

即使切片包含一个指针,它本身也是一个值,理解这一点很重要。在幕后,它是一个包含指针和长度的结构值。它不是指向结构的指针。

因此,您要么需要传递一个指针,要么需要将切片作为值返回,如果您想使用 append 修改它。

如果您只想修改切片的内容,您可以简单地按值传递切片:

尽管切片头是按值传递的,但头包含一个指向数组元素的指针,因此原始切片头和传递给函数的头的副本描述了相同的数组。因此,当函数返回时,可以通过原始切片变量看到修改后的元素。

使用 append 您正在修改切片标头。和

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

或者:

让函数修改切片头的另一种方法是传递一个指向它的指针。


查看完整回答
反对 回复 2021-10-04
  • 1 回答
  • 0 关注
  • 251 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信