如何解决Go中的指针与值接收器heap.Interface与sort.Interface
我在heap.Interface包下遇到了优先级队列示例
链接:https://golang.org/pkg/container/heap/#Interface
对于Push()
所需的Pop()
和heap.Interface
函数,实现是在指针接收器上进行的。但是对于Swap()
所需的sort.Interface
函数,实现是有价值的。
为什么会有这种区别?
据我了解,Push()
和Pop()
是在指针类型上实现的,因为它们需要更改基础数据。但是按照这种逻辑,Swap()
也应该在指针类型上实现。
Swap()
实现如何以及为什么对值起作用,而Push()
和Pop()
却不起作用?
解决方法
当需要修改传递的值时,需要一个指针接收器。对于Swap
,虽然支持切片的数组确实会被修改,但值本身(作为切片)不会被修改。
在Push
和Pop
的情况下,切片确实被修改了,因为在两种情况下,长度都改变了(在Push
情况下,如果基础数组已达到其容量,则可以替换为新数组。
看看Push
的实现:
func (pq *PriorityQueue) Push(x interface{}) {
n := len(*pq)
item := x.(*Item)
item.index = n
*pq = append(*pq,item) // Here,the slice is assigned a new value
}
Push
(和Pop
)修改基础切片以及优先级队列的切片元素,而Swap
仅交换切片中的两个元素,并且不会更改切片本身。因此,Swap
可以与值接收器一起使用。
在内部,切片变量保存长度,容量和指向数据的指针。交换项目会更改数据,但不会更改切片标头中的任何项目。拉斯·考克斯explained this in a blog post。
向切片中添加项目(例如将某些内容推送到堆上)可能需要重新分配数组,这将更改容量和需要指向的位置。
您可能会发现this answer on pointers vs. values generally是有用的。还有其他类型,例如通道和地图,其中包含引用,因此您不需要指针就可以弄乱下面的数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。